package com.hskn.hss.module.bigscreen.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hskn.hss.exception.HssException;
import com.hskn.hss.module.alarmcar.entity.Abnormal;
import com.hskn.hss.module.alarmcar.entity.AlarmCar;
import com.hskn.hss.module.alarmcar.mapper.AlarmCarMapper;
import com.hskn.hss.module.alarmperson.entity.AlarmPerson;
import com.hskn.hss.module.alarmperson.mapper.AlarmPersonMapper;
import com.hskn.hss.module.alarmsheshi.entity.AlarmSheshi;
import com.hskn.hss.module.alarmsheshi.mapper.AlarmSheshiMapper;
import com.hskn.hss.module.bigscreen.entity.vo.*;
import com.hskn.hss.module.bigscreen.entity.vo.jxqsscene.JxqsWorkPlan;
import com.hskn.hss.module.bigscreen.mapper.BigScreenMapper;
import com.hskn.hss.module.bigscreen.service.IBigScreenService;
import com.hskn.hss.module.bigscreen.to.WorkPlanTo;
import com.hskn.hss.module.bigscreen.vo.*;
import com.hskn.hss.module.carTrack.entity.CarTrack;
import com.hskn.hss.module.carTrack.mapper.CarTrackMapper;
import com.hskn.hss.module.carviolation.entity.CarViolation;
import com.hskn.hss.module.carviolation.mapper.CarViolationMapper;
import com.hskn.hss.module.dataBigscreen.vo.AbnormalTypeVo;
import com.hskn.hss.module.depart.entity.SysDepart;
import com.hskn.hss.module.depart.mapper.SysDepartMapper;
import com.hskn.hss.module.dlbjviolation.entity.DlbjViolation;
import com.hskn.hss.module.dlbjviolation.mapper.DlbjViolationMapper;
import com.hskn.hss.module.employeePunchCard.entity.EmployeePunchCard;
import com.hskn.hss.module.employeePunchCard.mapper.EmployeePunchCardMapper;
import com.hskn.hss.module.grid.entity.Grid;
import com.hskn.hss.module.grid.mapper.GridMapper;
import com.hskn.hss.module.grid.service.IGridService;
import com.hskn.hss.module.gridBindCheckWork.entity.GridBindCheckwork;
import com.hskn.hss.module.gridBindCheckWork.service.GridBindCheckWorkService;
import com.hskn.hss.module.jobset.entity.Jobset;
import com.hskn.hss.module.jobset.mapper.JobsetMapper;
import com.hskn.hss.module.rptCarWork.entity.RptCarWork;
import com.hskn.hss.module.rptCarWork.mapper.RptCarWorkMapper;
import com.hskn.hss.module.rptEmployeeWork.entity.RptEmployeeWork;
import com.hskn.hss.module.rptEmployeeWork.mapper.RptEmployeeWorkMapper;
import com.hskn.hss.module.tlcar.entity.TICarResult;
import com.hskn.hss.module.tlcar.entity.TlCar;
import com.hskn.hss.module.tlcar.mapper.TlCarMapper;
import com.hskn.hss.module.tlemergentplan.entity.TlEmergentPlan;
import com.hskn.hss.module.tlemergentplan.mapper.TlEmergentPlanMapper;
import com.hskn.hss.module.tlemployee.entity.TlEmployee;
import com.hskn.hss.module.tlemployee.mapper.TlEmployeeMapper;
import com.hskn.hss.module.tlequip.entity.TlEquip;
import com.hskn.hss.module.tlequip.mapper.TlEquipMapper;
import com.hskn.hss.module.tlresplan.entity.TlEmergentResplan;
import com.hskn.hss.module.tlresplan.mapper.TlEmergentResplanMapper;
import com.hskn.hss.module.tlthreshold.entity.TlThreshold;
import com.hskn.hss.module.tlthreshold.mapper.TlThresholdMapper;
import com.hskn.hss.module.tlworktype.entity.TlWorkType;
import com.hskn.hss.module.tlworktype.mapper.TlWorkTypeMapper;
import com.hskn.hss.module.user.entity.User;
import com.hskn.hss.module.user.mapper.UserMapper;
import com.hskn.hss.module.workkaoqin.entity.WorkKaoqin;
import com.hskn.hss.module.workkaoqin.mapper.WorkKaoqinMapper;
import com.hskn.hss.module.workruleitem.entity.WorkRuleItem;
import com.hskn.hss.module.workruleitem.mapper.WorkRuleItemMapper;
import com.hskn.hss.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hskn
 * @since 2021-05-17
 */
@Slf4j
@Service
public class BigScreenServiceImpl implements IBigScreenService {

    @Resource
    private BigScreenMapper bigScreenMapper;
    @Resource
    private TlEmployeeMapper tlEmployeeMapper;
    @Resource
    TlCarMapper tlCarMapper;
    @Resource
    RptCarWorkMapper rptCarWorkMapper;
    @Resource
    private RptEmployeeWorkMapper rptEmployeeWorkMapper;
    @Resource
    private GridMapper gridMapper;
    @Resource
    private IGridService iGridService;
    @Resource
    private CarTrackMapper carTrackMapper;
    @Resource
    private LocationUtils locationUtil;
    @Resource
    private WorkKaoqinMapper workKaoqinMapper;
    @Resource
    private JobsetMapper jobsetMapper;
    @Resource
    private AlarmCarMapper alarmCarMapper;
    @Resource
    private CarViolationMapper carViolationMapper;
    @Resource
    private AlarmPersonMapper alarmPersonMapper;
    @Resource
    private DlbjViolationMapper dlbjViolationMapper;
    @Resource
    private AlarmSheshiMapper alarmSheshiMapper;
    @Resource
    TlThresholdMapper tlThresholdMapper;
    @Resource
    WorkRuleItemMapper workRuleItemMapper;
    @Resource
    private SysDepartMapper sysDepartMapper;
    @Resource
    private TlWorkTypeMapper tlWorkTypeMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private EmployeePunchCardMapper employeePunchCardMapper;
    @Resource
    private TlEquipMapper tlEquipMapper;
    @Resource
    private TlEmergentPlanMapper tlEmergentPlanMapper;
    @Resource
    private TlEmergentResplanMapper tlEmergentResplanMapper;
    @Resource
    private GridBindCheckWorkService gridBindCheckWorkService;


    @Override
    public EmployeeMonitorVo personMonitor() {

        Set<String> employeeIdList = new HashSet<>();
        QueryWrapper<RptEmployeeWork> rptEmployeeWorkQueryWrapper = new QueryWrapper<>();
        rptEmployeeWorkQueryWrapper.lambda().eq(RptEmployeeWork::getWorkDate, StringUtils.dateToStr(new Date(), "yyyy-MM-dd"));
        List<RptEmployeeWork> rptEmployeeWorkList = rptEmployeeWorkMapper.selectList(rptEmployeeWorkQueryWrapper);
        rptEmployeeWorkList.forEach(rptEmployeeWork -> {
            employeeIdList.add(rptEmployeeWork.getEmployeeId());
        });

        Integer totalOnlineNumEmp = 0;
        Integer totalONumEmp = 0;

        Integer totalChuQinNumEmp = 0;
        Integer totalANumEmp = 0;

        QueryWrapper<TlEquip> tlEquipQueryWrapper = new QueryWrapper<>();
        tlEquipQueryWrapper.lambda().eq(TlEquip::getOnlinestatus, "0");
        List<TlEquip> tlEquipList = tlEquipMapper.selectList(tlEquipQueryWrapper);
        if (CollectionUtils.isEmpty(employeeIdList)) {
            employeeIdList.add("-1");
        }
        QueryWrapper<TlEmployee> tlEmployeeQueryWrapper = new QueryWrapper<>();
        tlEmployeeQueryWrapper.lambda().in(TlEmployee::getId, employeeIdList);
        List<TlEmployee> tlEmployeeList = tlEmployeeMapper.selectList(tlEmployeeQueryWrapper);

        List<TlEmployee> tlEmployeeFilterAttendance = tlEmployeeList.stream().filter(tlEmployee -> StringUtils.isNotEmpty(tlEmployee.getAttendance()) && tlEmployee.getAttendance() == 0).collect(toList());

        Map<String, TlEmployee> stringTlEmployeeMap = tlEmployeeList.stream().collect(Collectors.groupingBy(TlEmployee::getId, Collectors.collectingAndThen(Collectors.toList(), tlEmployees -> tlEmployees.get(0))));

        Map<String, List<TlEmployee>> stringListMap = tlEmployeeList.stream().filter(item -> StringUtils.isNotEmpty(item.getWorktype())).collect(Collectors.groupingBy(TlEmployee::getWorktype));

        Map<String, List<TlEmployee>> tlEmployeeFilterAttendanceMap = tlEmployeeFilterAttendance.stream().filter(item -> StringUtils.isNotEmpty(item.getWorktype())).collect(Collectors.groupingBy(TlEmployee::getWorktype));


        List<TlWorkType> tlWorkTypeList = tlWorkTypeMapper.selectList(new QueryWrapper<>());
        Map<String, TlWorkType> stringTlWorkTypeMap = tlWorkTypeList.stream().collect(Collectors.groupingBy(TlWorkType::getId, Collectors.collectingAndThen(Collectors.toList(), tlWorkTypes -> tlWorkTypes.get(0))));

        List<TlEquip> tlEmpEquipList = tlEquipList.stream()
                .filter(item -> StringUtils.isNotEmpty(item.getBindobjid()))
                .filter(item -> "dc605bf7800b204e3015ac977542e66b".equals(item.getEquiptypeid()))
                .collect(Collectors.toList());

        tlEmpEquipList.forEach(t -> {
            t.setBindtypeitem("");
            if (null != stringTlEmployeeMap.get(t.getBindobjid())) {
                t.setBindtypeitem(stringTlEmployeeMap.get(t.getBindobjid()).getWorktype());
            }
        });
        Map<String, List<TlEquip>> tlEmpEquipCollect = tlEmpEquipList.stream().collect(Collectors.groupingBy(TlEquip::getBindtypeitem));

        List<EmployeeOnlineIconVo> employeeOnlineIconVoList = new ArrayList<>();
        stringListMap.keySet().forEach(t -> {
            EmployeeOnlineIconVo employeeOnlineIconVo = new EmployeeOnlineIconVo();
            employeeOnlineIconVo.setWorkTypeId(t);
            employeeOnlineIconVo.setWorkTypeName("");
            if (null != stringTlWorkTypeMap.get(t)) {
                employeeOnlineIconVo.setWorkTypeName(stringTlWorkTypeMap.get(t).getWorktype());
                employeeOnlineIconVo.setWorkTypeIcon(stringTlWorkTypeMap.get(t).getEmployeeicon());
            }
            employeeOnlineIconVoList.add(employeeOnlineIconVo);
        });

        employeeOnlineIconVoList.forEach(t -> {
            t.setOnlineTotal(0);
            if (null != stringListMap.get(t.getWorkTypeId())) {
                t.setOnlineTotal(stringListMap.get(t.getWorkTypeId()).size());
            }
            t.setOnlineCount(0);
            if (null != tlEmpEquipCollect.get(t.getWorkTypeId())) {
                t.setOnlineCount(tlEmpEquipCollect.get(t.getWorkTypeId()).size());
            }

        });
        for (EmployeeOnlineIconVo employeeOnlineIconVo : employeeOnlineIconVoList) {
            totalOnlineNumEmp += null == employeeOnlineIconVo.getOnlineCount() ? 0 : employeeOnlineIconVo.getOnlineCount();
            totalONumEmp += null == employeeOnlineIconVo.getOnlineTotal() ? 0 : employeeOnlineIconVo.getOnlineTotal();
        }

        List<EmployeeAttendanceIconVo> employeeAttendanceIconVoList = new ArrayList<>();
        stringListMap.keySet().forEach(t -> {
            EmployeeAttendanceIconVo employeeAttendanceIconVo = new EmployeeAttendanceIconVo();
            employeeAttendanceIconVo.setWorkTypeId(t);
            employeeAttendanceIconVo.setWorkTypeName("");
            if (null != stringTlWorkTypeMap.get(t)) {
                employeeAttendanceIconVo.setWorkTypeName(stringTlWorkTypeMap.get(t).getWorktype());
                employeeAttendanceIconVo.setWorkTypeIcon(stringTlWorkTypeMap.get(t).getEmployeeicon());
            }

            employeeAttendanceIconVoList.add(employeeAttendanceIconVo);

        });

        employeeAttendanceIconVoList.forEach(t -> {
            t.setChuQinTotal(0);
            if (null != stringListMap.get(t.getWorkTypeId())) {
                t.setChuQinTotal(stringListMap.get(t.getWorkTypeId()).size());
            }
            t.setChuQinCount(0);
            if (null != tlEmployeeFilterAttendanceMap.get(t.getWorkTypeId())) {
                t.setChuQinCount(tlEmployeeFilterAttendanceMap.get(t.getWorkTypeId()).size());
            }

        });
        for (EmployeeAttendanceIconVo employeeAttendanceIconVo : employeeAttendanceIconVoList) {
            totalChuQinNumEmp += null == employeeAttendanceIconVo.getChuQinCount() ? 0 : employeeAttendanceIconVo.getChuQinCount();
            totalANumEmp += null == employeeAttendanceIconVo.getChuQinTotal() ? 0 : employeeAttendanceIconVo.getChuQinTotal();
        }


        BigDecimal onlineRate = BigDecimal.ZERO;
        BigDecimal chuQinRate = BigDecimal.ZERO;
        if (totalONumEmp != 0) {
            onlineRate = (new BigDecimal(totalOnlineNumEmp).divide(new BigDecimal(totalONumEmp), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100))).setScale(0, BigDecimal.ROUND_UP);
            chuQinRate = (new BigDecimal(totalChuQinNumEmp).divide(new BigDecimal(totalONumEmp), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100))).setScale(0, BigDecimal.ROUND_UP);
        }

        EmployeeMonitorVo employeeMonitorVo = new EmployeeMonitorVo();
        employeeMonitorVo.setTotal(totalONumEmp);
        employeeMonitorVo.setOnlineCount(totalOnlineNumEmp);
        employeeMonitorVo.setOnlineRate(onlineRate);
        employeeMonitorVo.setEmployeeOnlineIconVoList(employeeOnlineIconVoList);

        employeeMonitorVo.setChuQinCount(totalChuQinNumEmp);
        employeeMonitorVo.setChuQinRate(chuQinRate);
        employeeMonitorVo.setEmployeeAttendanceIconVoList(employeeAttendanceIconVoList);
        return employeeMonitorVo;
    }

    @Override
    public CarMonitoringVo mechanicalCarMonitor() {
        Set<String> carIds = new HashSet<>();
        QueryWrapper<RptCarWork> rptCarWorkQueryWrapper = new QueryWrapper<>();
        rptCarWorkQueryWrapper.lambda().eq(RptCarWork::getWorkDate, StringUtils.dateToStr(new Date(), "yyyy-MM-dd"));
        List<RptCarWork> rptCarWorkList = rptCarWorkMapper.selectList(rptCarWorkQueryWrapper);
        for (RptCarWork rptCarWork : rptCarWorkList) {
            if (rptCarWork.getWorkType() == 2) {
                carIds.add(rptCarWork.getCarId());
            }
        }
//        QueryWrapper<GridBindCheckwork> gridBindCheckworkQueryWrapper = new QueryWrapper<>();
//        gridBindCheckworkQueryWrapper.lambda().eq(GridBindCheckwork::getDate, StringUtils.dateToStr(new Date(), "yyyy-MM-dd"));
//        List<GridBindCheckwork> gridBindCheckworkList = gridBindCheckWorkService.list(gridBindCheckworkQueryWrapper);
//        for (GridBindCheckwork gridBindCheckwork : gridBindCheckworkList) {
//            if (gridBindCheckwork.getUpStatus() == 2||gridBindCheckwork.getUpStatus() == 1) {
//                carIds.add(gridBindCheckwork.getItemId());
//            }
//        }
        Integer total = 0;
        Integer onlineCount = 0;
        Integer chuQinCount = 0;
        if (CollectionUtils.isEmpty(carIds)) {
            carIds.add("-1");
        }
        //查询所有车辆，以车辆类型分组，获取总数、在线数、在岗数
        List<TICarResult> carResults = tlCarMapper.getNumByCarType(carIds);
        //获取总人数、在线总人数、在岗总人数
        for (TICarResult carResult : carResults) {
            total += carResult.getNum();
            onlineCount += carResult.getOnlinum();
            chuQinCount += carResult.getChuqinnum();
        }
        BigDecimal onlineRate = BigDecimal.ZERO;
        BigDecimal chuqinRate = BigDecimal.ZERO;
        if (total != 0) {
            onlineRate = (new BigDecimal(onlineCount).divide(new BigDecimal(total), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100))).setScale(0, BigDecimal.ROUND_UP);

            chuqinRate = (new BigDecimal(chuQinCount).divide(new BigDecimal(total), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100))).setScale(0, BigDecimal.ROUND_UP);

        }
        CarMonitoringVo carMonitoringVo = new CarMonitoringVo();
        carMonitoringVo.setTotal(total);
        carMonitoringVo.setOnlineCount(onlineCount);
        carMonitoringVo.setOnlineRate(onlineRate);
        carMonitoringVo.setChuQinCount(chuQinCount);
        carMonitoringVo.setChuQinRate(chuqinRate);
        carMonitoringVo.setCarResults(carResults);
        return carMonitoringVo;
    }

    @Override
    public CarMonitoringVo pickupCarMonitor() {
        Set<String> carIds = new HashSet<>();
        QueryWrapper<RptCarWork> rptCarWorkQueryWrapper = new QueryWrapper<>();
        rptCarWorkQueryWrapper.lambda().eq(RptCarWork::getWorkDate, StringUtils.dateToStr(new Date(), "yyyy-MM-dd"));
        List<RptCarWork> rptCarWorkList = rptCarWorkMapper.selectList(rptCarWorkQueryWrapper);
        for (RptCarWork rptCarWork : rptCarWorkList) {
            if (rptCarWork.getWorkType() == 3) {
                carIds.add(rptCarWork.getCarId());
            }
        }
//        QueryWrapper<GridBindCheckwork> gridBindCheckworkQueryWrapper = new QueryWrapper<>();
//        gridBindCheckworkQueryWrapper.lambda().eq(GridBindCheckwork::getDate, StringUtils.dateToStr(new Date(), "yyyy-MM-dd"));
//        List<GridBindCheckwork> gridBindCheckworkList = gridBindCheckWorkService.list(gridBindCheckworkQueryWrapper);
//        for (GridBindCheckwork gridBindCheckwork : gridBindCheckworkList) {
//            if (gridBindCheckwork.getUpStatus() == 2||gridBindCheckwork.getUpStatus() == 1) {
//                carIds.add(gridBindCheckwork.getItemId());
//            }
//        }
        Integer total = 0;
        Integer onlineCount = 0;
        Integer chuQinCount = 0;
        if (CollectionUtils.isEmpty(carIds)) {
            carIds.add("-1");
        }
        //查询所有车辆，以车辆类型分组，获取总数、在线数、在岗数
        List<TICarResult> carResults = tlCarMapper.getNumByCarType(carIds);
        //获取总人数、在线总人数、在岗总人数
        for (TICarResult carResult : carResults) {
            total += carResult.getNum();
            onlineCount += carResult.getOnlinum();
            chuQinCount += carResult.getChuqinnum();
        }
        BigDecimal onlineRate = BigDecimal.ZERO;
        BigDecimal chuqinRate = BigDecimal.ZERO;
        if (total != 0) {
            onlineRate = (new BigDecimal(onlineCount).divide(new BigDecimal(total), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100))).setScale(0, BigDecimal.ROUND_UP);

            chuqinRate = (new BigDecimal(chuQinCount).divide(new BigDecimal(total), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100))).setScale(0, BigDecimal.ROUND_UP);

        }
        CarMonitoringVo carMonitoringVo = new CarMonitoringVo();
        carMonitoringVo.setTotal(total);
        carMonitoringVo.setOnlineCount(onlineCount);
        carMonitoringVo.setOnlineRate(onlineRate);
        carMonitoringVo.setChuQinCount(chuQinCount);
        carMonitoringVo.setChuQinRate(chuqinRate);
        carMonitoringVo.setCarResults(carResults);
        return carMonitoringVo;
    }


    @Override
    public List<Guideboard> guideBoards(JSONObject params) throws HssException {

        List<Guideboard> guideBoards = bigScreenMapper.guideBoards(params);

        return guideBoards;
    }

    private List<Grid> getAllChildrenByGridId(String id, Map<String, Grid> mapAll) {
        List<Grid> childrenList = new ArrayList<>();
        Grid newGrid = new Grid();
        BeanUtils.copyProperties(mapAll.get(id), newGrid);
        childrenList.add(newGrid);
        if ("潍州路-健康街至潍胶路".equals(newGrid.getName())) {
            System.out.println(newGrid.getChildren());

            System.out.println(newGrid.getName());
        }
        System.out.println(newGrid.getName());
        System.out.println(newGrid.getChildren());
        for (Grid child : mapAll.get(id).getChildren()) {
            getAllChildrenByGridId(child.getGridId(), mapAll).forEach(t -> {
                Grid newChildGrid = new Grid();
                BeanUtils.copyProperties(t, newChildGrid);
                childrenList.add(newChildGrid);
            });
        }
        return childrenList;
    }

    @Override
    public List<Guideboard> treeData(JSONObject params) {
        long carSTime1 = System.currentTimeMillis();
        String levelId = params.getString("levelId");
        // 所有的
        List<Grid> listAll = iGridService.list();
        for (Grid grid : listAll) {
            grid.setChildren(new ArrayList<>());
            listAll.stream().filter(t -> null != t.getParentGridIds() && t.getParentGridIds().contains(grid.getGridId())).collect(Collectors.toList()).forEach(t -> {
                Grid g = new Grid();
                BeanUtils.copyProperties(t, g);
                grid.getChildren().add(g);
            });
        }
        Map<String, Grid> mapAll = listAll.stream().collect(Collectors.toMap(Grid::getGridId, t -> t));

        long carSTime2 = System.currentTimeMillis();
        log.info("=====carLocationHandle2=执行时间(毫秒)：{}", carSTime2 - carSTime1);
        // 只看是路牌的
        List<Grid> listRoad = new ArrayList<>();
        listAll.stream().filter(t -> (null != t.getIsGuideboard() && t.getIsGuideboard() == 1) && (null != t.getIsEnable() && t.getIsEnable() == 1)).collect(Collectors.toList()).forEach(k -> {
            Grid g = new Grid();
            BeanUtils.copyProperties(k, g);
            listRoad.add(g);
        });

        listRoad.forEach(t -> {
            List<Grid> childGridList = getAllChildrenByGridId(t.getGridId(), mapAll);
            childGridList.forEach(t1 -> t1.setChildren(new ArrayList<>()));
            t.setChildren(childGridList);
        });

        long carSTime3 = System.currentTimeMillis();
        log.info("=====carLocationHandle3=执行时间(毫秒)：{}", carSTime3 - carSTime2);
        // 生成页面渲染需要的元素
        List<Guideboard> guideboardList = new ArrayList<>();
        listRoad.forEach(t -> {
            Guideboard guideboard = new Guideboard();
            guideboard.setGridId(t.getGridId());
            guideboard.setGridName(t.getName());
            guideboard.setLevelId(t.getLevelid());
            guideboard.setLevelName(t.getLevelName());
            guideboard.setLnglat(t.getLnglat());
            guideboard.setChilds(new ArrayList<>());
            t.getChildren().forEach(t1 -> {
                GuideboardItem guideboardItem = new GuideboardItem();
                guideboardItem.setGridId(t1.getGridId());
                guideboardItem.setGridName(t1.getName());
                guideboardItem.setLevelId(t1.getLevelid());
                guideboardItem.setLevelName(t1.getLevelName());
                guideboardItem.setLnglat(t1.getLnglat());
                guideboardItem.setArea(t1.getArea());
                guideboardItem.setKm(t1.getKm());
                guideboardItem.setIsGuideboard(t1.getIsGuideboard());
                guideboardItem.setCars(new HashSet<>());
                guideboardItem.setDepts(new ArrayList<>());
                guideboard.getChilds().add(guideboardItem);
            });
            guideboardList.add(guideboard);
        });

        long carSTime4 = System.currentTimeMillis();
        log.info("=====carLocationHandle4=执行时间(毫秒)：{}", carSTime4 - carSTime3);
        // 查询车和人需要的网格id
        Set<String> gridIdList = new HashSet<>();
        listRoad.forEach(t -> {
            t.getChildren().forEach(t1 -> gridIdList.add(t.getGridId()));
        });

        if (!gridIdList.isEmpty()) {

            long carSTime5 = System.currentTimeMillis();
            log.info("=====carLocationHandle5=执行时间(毫秒)：{}", carSTime5 - carSTime4);
            long carSTime6 = System.currentTimeMillis();
            log.info("=====carLocationHandle6=执行时间(毫秒)：{}", carSTime6 - carSTime5);
            Map<String, TlEmployee> tlEmployeeMap = tlEmployeeMapper.selectList(new QueryWrapper<>()).stream().collect(Collectors.groupingBy(TlEmployee::getId,
                    Collectors.collectingAndThen(Collectors.toList(), tlEmployees -> tlEmployees.get(0))));
            long carSTime7 = System.currentTimeMillis();
            log.info("=====carLocationHandle7=执行时间(毫秒)：{}", carSTime7 - carSTime6);
            Map<String, SysDepart> sysDepartMap = sysDepartMapper.selectList(new QueryWrapper<>()).stream().collect(Collectors.groupingBy(SysDepart::getId,
                    Collectors.collectingAndThen(Collectors.toList(), sysDeparts -> sysDeparts.get(0))));
            long carSTime8 = System.currentTimeMillis();
            log.info("=====carLocationHandle8=执行时间(毫秒)：{}", carSTime8 - carSTime7);
            Map<String, TlWorkType> tlWorkTypeMap = tlWorkTypeMapper.selectList(new QueryWrapper<>()).stream().collect(Collectors.groupingBy(TlWorkType::getId,
                    Collectors.collectingAndThen(Collectors.toList(), tlWorkTypes -> tlWorkTypes.get(0))));
            long carSTime9 = System.currentTimeMillis();
            log.info("=====carLocationHandle9=执行时间(毫秒)：{}", carSTime9 - carSTime8);
            Map<String, User> userMap = userMapper.selectList(new QueryWrapper<>()).stream().collect(Collectors.groupingBy(User::getUid,
                    Collectors.collectingAndThen(Collectors.toList(), users -> users.get(0))));

            long carSTime10 = System.currentTimeMillis();
            log.info("=====carLocationHandle10=执行时间(毫秒)：{}", carSTime10 - carSTime9);
            QueryWrapper<RptEmployeeWork> employeeWorkQueryWrapper = new QueryWrapper<>();
            employeeWorkQueryWrapper.lambda().eq(RptEmployeeWork::getWorkDate, StringUtils.dateToStr(new Date(), "yyyy-MM-dd"));
            List<RptEmployeeWork> rptEmployeeWorkList = rptEmployeeWorkMapper.selectList(employeeWorkQueryWrapper);

            long carSTime11 = System.currentTimeMillis();
            log.info("=====carLocationHandle11=执行时间(毫秒)：{}", carSTime11 - carSTime10);

            List<RptWorkPlanVo> rptWorkPlanVoList = new ArrayList<>();
            rptEmployeeWorkList.forEach(rptEmployeeWork -> {
                RptWorkPlanVo rptWorkPlanVo = new RptWorkPlanVo();
                rptWorkPlanVo.setPersonId(rptEmployeeWork.getEmployeeId());
                rptWorkPlanVo.setGridId(rptEmployeeWork.getGridId());
                rptWorkPlanVo.setStatus(rptEmployeeWork.getStatus());
                rptWorkPlanVo.setTimeConsuming(Tools.secondToTime(rptEmployeeWork.getNowProgress().longValue()));
                TlEmployee tlEmployee = tlEmployeeMap.get(rptEmployeeWork.getEmployeeId());
                if (null != tlEmployee) {
                    rptWorkPlanVo.setPersonName(tlEmployee.getName());
                    rptWorkPlanVo.setDepId(tlEmployee.getEmpldeptid());
                    rptWorkPlanVo.setPersonPhoto(tlEmployee.getPersonphoto());
                    SysDepart sysDepart = sysDepartMap.get(tlEmployee.getDeptid());
                    if (null != sysDepart) {
                        rptWorkPlanVo.setDepName(sysDepart.getDepartName());
                        User user = userMap.get(sysDepart.getPrincipalUid());
                        if (null != user) {
                            rptWorkPlanVo.setLeaderId(user.getUid());
                            rptWorkPlanVo.setLeaderName(user.getName());
                            rptWorkPlanVo.setLeaderPhone(user.getPhone());
                        }
                    }
                    TlWorkType tlWorkType = tlWorkTypeMap.get(tlEmployee.getWorktype());
                    if (null != tlWorkType) {
                        rptWorkPlanVo.setPersonTypeId(tlWorkType.getId());
                        rptWorkPlanVo.setPersonTypeName(tlWorkType.getWorktype());
                    }
                }
                rptWorkPlanVoList.add(rptWorkPlanVo);
            });


            List<RptWorkPlanVo> rptWorkPlanVoCollect = rptWorkPlanVoList.stream().filter(rptWorkPlanVo -> null != rptWorkPlanVo.getGridId() && gridIdList.contains(rptWorkPlanVo.getGridId())).collect(Collectors.toList());
            Map<String, List<RptWorkPlanVo>> workPlanDayMap = rptWorkPlanVoCollect.stream().collect(Collectors.groupingBy(RptWorkPlanVo::getGridId));
            Map<String, Map<String, List<RptWorkPlanVo>>> rptWorkPlanMap2 = new HashMap<>();
            workPlanDayMap.keySet().forEach(k -> {
                rptWorkPlanMap2.put(k, workPlanDayMap.get(k).stream().filter(rptWorkPlanVo -> null != rptWorkPlanVo.getDepId() && !"".equals(rptWorkPlanVo.getDepId())).collect(Collectors.groupingBy(RptWorkPlanVo::getDepId)));
            });


            //车辆
            Set<String> carIds = new HashSet<>();
            QueryWrapper<RptCarWork> rptCarWorkQueryWrapper = new QueryWrapper<>();
            rptCarWorkQueryWrapper.lambda().eq(RptCarWork::getWorkDate, StringUtils.dateToStr(new Date(), "yyyy-MM-dd"));
            rptCarWorkQueryWrapper.lambda().in(RptCarWork::getGridId, gridIdList);
            List<RptCarWork> rptCarWorkList = rptCarWorkMapper.selectList(rptCarWorkQueryWrapper);
            rptCarWorkList.forEach(rptCarWork -> {
                carIds.add(rptCarWork.getCarId());
            });

            if (null != carIds && !carIds.isEmpty()) {
                QueryWrapper<TlCar> tlCarQueryWrapper = new QueryWrapper<>();
                tlCarQueryWrapper.lambda().in(TlCar::getId, carIds);
                List<TlCar> tlCarList = tlCarMapper.selectList(tlCarQueryWrapper);
                tlCarList.forEach(tlCar -> {
                    TlEmployee tlEmployee = tlEmployeeMap.get(tlCar.getDriverid());
                    if (null != tlEmployee) {
                        tlCar.setDriverName(tlEmployee.getName());
                    }
                });
                System.out.println("========================");
                // 将数据加载进返回体
                guideboardList.forEach(t -> {
                    for (GuideboardItem child : t.getChilds()) {
                        GuideboardItem t1 = child;
                        if (!rptWorkPlanMap2.isEmpty() && t1.getGridId() != null && null != rptWorkPlanMap2.get(t1.getGridId())) {
                            for (String k : rptWorkPlanMap2.get(t1.getGridId()).keySet()) {
                                GuideboardItemDept guideboardItemDept = new GuideboardItemDept();
                                if (t1.getDeptMap() == null || t1.getDeptMap().get(k) == null) {
                                    guideboardItemDept.setDepId(k);
                                    guideboardItemDept.setDepName(rptWorkPlanMap2.get(t1.getGridId()).get(k).get(0).getDepName());
                                    guideboardItemDept.setLeaderId(rptWorkPlanMap2.get(t1.getGridId()).get(k).get(0).getLeaderId());
                                    guideboardItemDept.setLeaderName(rptWorkPlanMap2.get(t1.getGridId()).get(k).get(0).getLeaderName());
                                    guideboardItemDept.setLeaderPhone(rptWorkPlanMap2.get(t1.getGridId()).get(k).get(0).getLeaderPhone());
                                    guideboardItemDept.setPersonPhoto(rptWorkPlanMap2.get(t1.getGridId()).get(k).get(0).getPersonPhoto());

                                    guideboardItemDept.setPersons(new ArrayList<>());

                                    t1.getDepts().add(guideboardItemDept);
                                    if (t1.getDeptMap() == null) {
                                        t1.setDeptMap(new HashMap<>());
                                    }
                                    if (t1.getDeptMap().get(k) == null) {
                                        t1.getDeptMap().put(k, new ArrayList<>());
                                    }
                                }

                                rptWorkPlanMap2.get(t1.getGridId()).get(k).forEach(p -> {
                                    if (!t1.getDeptMap().get(k).contains(p.getPersonId())) {
                                        GuideboardItemPerson guideboardItemPerson = new GuideboardItemPerson();
                                        guideboardItemPerson.setPersonId(p.getPersonId());
                                        guideboardItemPerson.setPersonName(p.getPersonName());
                                        guideboardItemPerson.setPersonTypeId(p.getPersonTypeId());
                                        guideboardItemPerson.setPersonTypeName(p.getPersonTypeName());
                                        guideboardItemPerson.setPhone(p.getLeaderPhone());
                                        guideboardItemPerson.setPersonPhoto(p.getPersonPhoto());
                                        guideboardItemPerson.setTimeConsuming(p.getTimeConsuming());
                                        guideboardItemPerson.setStatus(p.getStatus());
                                        guideboardItemDept.getPersons().add(guideboardItemPerson);

                                        t1.getDeptMap().get(k).add(p.getPersonId());
                                    }
                                });

                                if (t1.getDeptMap() == null || t1.getDeptMap().get(k) == null) {
                                    t1.getDepts().add(guideboardItemDept);
                                }
                            }
                        }
                        if (!rptCarWorkList.isEmpty() && t1.getGridId() != null) {
                            for (RptCarWork rptCarWork : rptCarWorkList) {
                                if (rptCarWork.getGridId().equals(t1.getGridId())) {
                                    String carId = rptCarWork.getCarId();
                                    List<TlCar> tlCarList1 = tlCarList.stream().filter(t2 -> t2.getId().equals(carId)).collect(Collectors.toList());
                                    if (tlCarList1.size() > 0) {
                                        GuideboardItemCar guideboardItemCar = new GuideboardItemCar();
                                        guideboardItemCar.setCarId(tlCarList1.get(0).getId());
                                        guideboardItemCar.setCarName(tlCarList1.get(0).getCarnumber());
                                        guideboardItemCar.setCarTypeId(tlCarList1.get(0).getCartypeid());
                                        guideboardItemCar.setCarTypeName(tlCarList1.get(0).getCarTypeName());
                                        guideboardItemCar.setDriverId(tlCarList1.get(0).getDriverid());
                                        if (StringUtils.isNotEmpty(tlCarList1.get(0).getDriverid())) {
                                            TlEmployee tlEmployee = tlEmployeeMap.get(tlCarList1.get(0).getDriverid());
                                            if (null != tlEmployee) {
                                                guideboardItemCar.setDriverPhoneNumber(tlEmployee.getPhonenum());
                                            }
                                        }
                                        guideboardItemCar.setDriverName(tlCarList1.get(0).getDriverName());
                                        guideboardItemCar.setMileage(rptCarWork.getWorkMileage().divide(new BigDecimal(1000), 1, BigDecimal.ROUND_HALF_UP));
                                        guideboardItemCar.setStatus(rptCarWork.getStatus());
                                        guideboardItemCar.setCarPicture(tlCarList1.get(0).getCarpicture());
                                        t1.getCars().add(guideboardItemCar);
                                    }
                                }
                            }
                        }
                    }
                });
            }


        }
        if (StringUtils.isNotEmpty(levelId)) {
            List<Guideboard> guideboardCollect = guideboardList.stream().filter(guideboard -> null != guideboard.getLevelId() && guideboard.getLevelId().equals(levelId)).collect(Collectors.toList());
            return guideboardCollect;
        } else {
            return guideboardList;
        }
    }


    private static List<Grid> getThree(List<Grid> list, String parentId) {
        //获取所有子节点
        List<Grid> childTreeList = getChildTree(list, parentId);
        for (Grid grid : childTreeList) {
            grid.setChildren(getThree(list, grid.getGridId()));
        }
        return childTreeList;
    }

    private static List<Grid> getChildTree(List<Grid> list, String id) {
        List<Grid> childTree = new ArrayList<>();
        for (Grid grid : list) {
            if (null != grid.getParentGridIds()) {
                if (grid.getParentGridIds().equals(id)) {
                    childTree.add(grid);
                }
            }
        }
        return childTree;
    }


    @Override
    public List<AbnormalTypeVo> expTypeCars() {
        List<AbnormalTypeVo> expTypeCarList = new ArrayList<>();

        QueryWrapper<TlThreshold> tlFacilitiesTypeItemsQueryWrapper = new QueryWrapper<>();
        tlFacilitiesTypeItemsQueryWrapper.eq("thresholdtype", "car");
        tlFacilitiesTypeItemsQueryWrapper.groupBy("alarmname");
        List<TlThreshold> tlThresholdList = tlThresholdMapper.selectList(tlFacilitiesTypeItemsQueryWrapper);
        for (TlThreshold tlThreshold : tlThresholdList
        ) {
            AbnormalTypeVo abnormalTypeVo = new AbnormalTypeVo();
            abnormalTypeVo.setName(tlThreshold.getAlarmname());
            abnormalTypeVo.setSysName(tlThreshold.getSysname());
            abnormalTypeVo.setType(0);
            expTypeCarList.add(abnormalTypeVo);
        }

        QueryWrapper<WorkRuleItem> workRuleItemListQueryWrapper = new QueryWrapper<>();
        workRuleItemListQueryWrapper.eq("rule_id", "jxqs_default");
        workRuleItemListQueryWrapper.groupBy("custom_name");
        List<WorkRuleItem> workRuleItemList = workRuleItemMapper.selectList(workRuleItemListQueryWrapper);
        for (WorkRuleItem workRuleItem : workRuleItemList
        ) {
            AbnormalTypeVo abnormalTypeVo = new AbnormalTypeVo();
            abnormalTypeVo.setName(workRuleItem.getCustomName());
            abnormalTypeVo.setSysName(workRuleItem.getSysName());
            abnormalTypeVo.setType(0);
            expTypeCarList.add(abnormalTypeVo);
        }
        return expTypeCarList;
    }

    @Override
    public List<AbnormalTypeVo> expTypePerson() {
        List<AbnormalTypeVo> expTypePersonList = new ArrayList<>();

        QueryWrapper<TlThreshold> tlFacilitiesTypeItemsQueryWrapper = new QueryWrapper<>();
        tlFacilitiesTypeItemsQueryWrapper.eq("thresholdtype", "person");
        tlFacilitiesTypeItemsQueryWrapper.groupBy("alarmname");
        List<TlThreshold> tlThresholdList = tlThresholdMapper.selectList(tlFacilitiesTypeItemsQueryWrapper);
        for (TlThreshold tlThreshold : tlThresholdList
        ) {
            AbnormalTypeVo abnormalTypeVo = new AbnormalTypeVo();
            abnormalTypeVo.setName(tlThreshold.getAlarmname());
            abnormalTypeVo.setSysName(tlThreshold.getSysname());
            abnormalTypeVo.setType(0);
            expTypePersonList.add(abnormalTypeVo);
        }

        QueryWrapper<WorkRuleItem> workRuleItemListQueryWrapper = new QueryWrapper<>();
        workRuleItemListQueryWrapper.eq("rule_id", "dlbj_default");
        workRuleItemListQueryWrapper.groupBy("custom_name");
        List<WorkRuleItem> workRuleItemList = workRuleItemMapper.selectList(workRuleItemListQueryWrapper);
        for (WorkRuleItem workRuleItem : workRuleItemList
        ) {
            AbnormalTypeVo abnormalTypeVo = new AbnormalTypeVo();
            abnormalTypeVo.setName(workRuleItem.getCustomName());
            abnormalTypeVo.setSysName(workRuleItem.getSysName());
            abnormalTypeVo.setType(1);
            expTypePersonList.add(abnormalTypeVo);
        }
        return expTypePersonList;
    }

    @Override
    public List<AbnormalTypeVo> expTypeFacilities() {
        List<AbnormalTypeVo> expTypeFacilitiesList = new ArrayList<>();

        QueryWrapper<TlThreshold> tlFacilitiesTypeItemsQueryWrapper = new QueryWrapper<>();
        tlFacilitiesTypeItemsQueryWrapper.eq("thresholdtype", "facl");
        tlFacilitiesTypeItemsQueryWrapper.groupBy("alarmname");
        List<TlThreshold> tlThresholdList = tlThresholdMapper.selectList(tlFacilitiesTypeItemsQueryWrapper);
        for (TlThreshold tlThreshold : tlThresholdList
        ) {
            AbnormalTypeVo abnormalTypeVo = new AbnormalTypeVo();
            abnormalTypeVo.setName(tlThreshold.getAlarmname());
            abnormalTypeVo.setSysName(tlThreshold.getSysname());
            abnormalTypeVo.setType(0);
            expTypeFacilitiesList.add(abnormalTypeVo);
        }
        return expTypeFacilitiesList;
    }

    @Override
    public JSONObject expCarList(ExpListTO expListTO) {
        JSONObject json = new JSONObject();
        try {
            //当日报警车辆
            QueryWrapper<AlarmCar> queryAlarmCarWrapper = new QueryWrapper<>();
            //当日违规车辆
            QueryWrapper<CarViolation> queryCarViolationWrapper = new QueryWrapper<>();

            //当日报警总次数
            QueryWrapper<AlarmCar> queryAlarmCarWrapper2 = new QueryWrapper<>();
            //当日违规总次数
            QueryWrapper<CarViolation> queryCarViolationWrapper2 = new QueryWrapper<>();

            //昨日异常车辆数
            QueryWrapper<AlarmCar> queryAlarmCarWrapper3 = new QueryWrapper<>();
            //昨日违规车辆数
            QueryWrapper<CarViolation> queryCarViolationWrapper3 = new QueryWrapper<>();

            //昨日异常总次数
            QueryWrapper<AlarmCar> queryAlarmCarWrapper4 = new QueryWrapper<>();
            //昨日异常总次数
            QueryWrapper<CarViolation> queryCarViolationWrapper4 = new QueryWrapper<>();

            //查询每种异常的数据
            Map map = new HashMap();
            //查询每种违规的数据
            Map map1 = new HashMap();
            //查询该辆车的该报警记录
            QueryWrapper<AlarmCar> queryAlarmWrapper = new QueryWrapper<>();

            String day = expListTO.getDate();
            String startTime = AttributeUtils.timeCompletion(day, 's');
            String endTime = AttributeUtils.timeCompletion(day, 'e');
            Date date = StringUtils.StringToDate3(day);
            Date date1 = new Date(date.getTime() - 1000 * 60 * 60 * 24);
            String yesToday = StringUtils.dateToStr(date1, "");
            String startTimeYesToday = AttributeUtils.timeCompletion(yesToday, 's');
            String endTimeYesToday = AttributeUtils.timeCompletion(yesToday, 'e');

            if (StringUtils.isNotEmpty(expListTO.getExpName())) {
                queryAlarmCarWrapper.lambda().eq(AlarmCar::getAlarmTypeName, expListTO.getExpName());
                queryCarViolationWrapper.lambda().eq(CarViolation::getRuleTypeName, expListTO.getExpName());
                queryAlarmCarWrapper2.lambda().eq(AlarmCar::getAlarmTypeName, expListTO.getExpName());
                queryCarViolationWrapper2.lambda().eq(CarViolation::getRuleTypeName, expListTO.getExpName());
                queryAlarmCarWrapper3.lambda().eq(AlarmCar::getAlarmTypeName, expListTO.getExpName());
                queryCarViolationWrapper3.lambda().eq(CarViolation::getRuleTypeName, expListTO.getExpName());
                queryAlarmCarWrapper4.lambda().eq(AlarmCar::getAlarmTypeName, expListTO.getExpName());
                queryCarViolationWrapper4.lambda().eq(CarViolation::getRuleTypeName, expListTO.getExpName());
                queryAlarmWrapper.lambda().eq(AlarmCar::getAlarmTypeName, expListTO.getExpName());
                map.put("expName", expListTO.getExpName());
                map1.put("expName", expListTO.getExpName());
            }
            if (StringUtils.isNotEmpty(expListTO.getType())) {
                queryAlarmCarWrapper.lambda().eq(AlarmCar::getCarTypeName, expListTO.getType());
                queryCarViolationWrapper.lambda().eq(CarViolation::getCarTypeName, expListTO.getType());
                queryAlarmCarWrapper2.lambda().eq(AlarmCar::getCarTypeName, expListTO.getType());
                queryCarViolationWrapper2.lambda().eq(CarViolation::getCarTypeName, expListTO.getType());
                queryAlarmCarWrapper3.lambda().eq(AlarmCar::getCarTypeName, expListTO.getType());
                queryCarViolationWrapper3.lambda().eq(CarViolation::getCarTypeName, expListTO.getType());
                queryAlarmCarWrapper4.lambda().eq(AlarmCar::getCarTypeName, expListTO.getType());
                queryCarViolationWrapper4.lambda().eq(CarViolation::getCarTypeName, expListTO.getType());
                queryAlarmWrapper.lambda().eq(AlarmCar::getCarTypeName, expListTO.getType());
                map.put("type", expListTO.getType());
                map1.put("type", expListTO.getType());
            }
            queryAlarmCarWrapper.lambda().between(AlarmCar::getAlarmTime, startTime, endTime);
            queryAlarmCarWrapper.lambda().groupBy(AlarmCar::getCarId);
            queryAlarmCarWrapper.lambda().orderByDesc(AlarmCar::getAlarmTime);
            queryCarViolationWrapper.lambda().between(CarViolation::getTime, startTime, endTime);
            queryCarViolationWrapper.lambda().groupBy(CarViolation::getCarId);
            queryCarViolationWrapper.lambda().orderByDesc(CarViolation::getTime);
            queryAlarmCarWrapper2.lambda().between(AlarmCar::getAlarmTime, startTime, endTime);
            queryAlarmCarWrapper2.lambda().orderByDesc(AlarmCar::getAlarmTime);
            queryCarViolationWrapper2.lambda().between(CarViolation::getTime, startTime, endTime);
            queryCarViolationWrapper2.lambda().orderByDesc(CarViolation::getTime);
            queryAlarmCarWrapper3.lambda().between(AlarmCar::getAlarmTime, startTimeYesToday, endTimeYesToday);
            queryAlarmCarWrapper3.lambda().groupBy(AlarmCar::getCarId);
            queryAlarmCarWrapper3.lambda().orderByDesc(AlarmCar::getAlarmTime);
            queryCarViolationWrapper3.lambda().between(CarViolation::getTime, startTimeYesToday, endTimeYesToday);
            queryCarViolationWrapper3.lambda().groupBy(CarViolation::getCarId);
            queryCarViolationWrapper3.lambda().orderByDesc(CarViolation::getTime);
            queryAlarmCarWrapper4.lambda().between(AlarmCar::getAlarmTime, startTimeYesToday, endTimeYesToday);
            queryAlarmCarWrapper4.lambda().orderByDesc(AlarmCar::getAlarmTime);
            queryCarViolationWrapper4.lambda().between(CarViolation::getTime, startTimeYesToday, endTimeYesToday);
            queryCarViolationWrapper4.lambda().orderByDesc(CarViolation::getTime);
            //当日异常车辆
            List<AlarmCar> expCpList = new ArrayList();
            //当日报警车辆
            List<AlarmCar> alarmCarToDayList = alarmCarMapper.selectList(queryAlarmCarWrapper);
            for (AlarmCar alarmCar : alarmCarToDayList
            ) {
                alarmCar.setExpType("1");
                alarmCar.setCarNameAndAlarmTypeName(alarmCar.getCarName() + "-" + alarmCar.getAlarmTypeName());
                expCpList.add(alarmCar);
            }
            //当日违规车辆
            List<CarViolation> carViolationToDayList = carViolationMapper.selectList(queryCarViolationWrapper);
            for (CarViolation carViolation : carViolationToDayList
            ) {
                AlarmCar alarmCarItem = new AlarmCar();
                alarmCarItem.setCarId(carViolation.getCarId());
                alarmCarItem.setDepId(carViolation.getDepid());
                alarmCarItem.setDepName(carViolation.getDepName());
                alarmCarItem.setAlarmTypeName(carViolation.getRuleTypeName());
                alarmCarItem.setCarName(carViolation.getCarName());
                alarmCarItem.setCarTypeName(carViolation.getCarTypeName());
                alarmCarItem.setExpType("2");
                alarmCarItem.setDealType(carViolation.getDealType());
                alarmCarItem.setCarNameAndAlarmTypeName(carViolation.getCarName() + "-" + carViolation.getRuleTypeName());
                alarmCarItem.setAlarmCarId(carViolation.getCarViolationId());
                alarmCarItem.setCreateTime(carViolation.getCreateTime());
                alarmCarItem.setContent(carViolation.getContent());
                alarmCarItem.setAlarmTypeId(carViolation.getRuleTypeId());
                alarmCarItem.setLng(carViolation.getLng());
                alarmCarItem.setLat(carViolation.getLat());
                alarmCarItem.setAddress(carViolation.getAddress());
                alarmCarItem.setAlarmTime(carViolation.getTime());
                alarmCarItem.setDealRemark(carViolation.getDealRemark());
                alarmCarItem.setCarTypeId(carViolation.getCarTypeId());
                alarmCarItem.setIsKeep(carViolation.getIsKeep());
                alarmCarItem.setDealUid(carViolation.getDealUid());
                alarmCarItem.setAlarmStartTime(carViolation.getViolationStartTime());
                alarmCarItem.setAlarmEndTime(carViolation.getViolationEndTime());
                expCpList.add(alarmCarItem);
            }
            Map<String, List<AlarmCar>> abnormalByCarIdMap = expCpList.stream().collect(Collectors.groupingBy(AlarmCar::getCarId));
            //当日异常车辆数量
            int expCp = 0;
            if (Objects.nonNull(abnormalByCarIdMap)) {
                expCp = abnormalByCarIdMap.size();
            }
            json.put("expCp", expCp);

            //当日异常车辆
            List<AlarmCar> expCpToDayList = new ArrayList();
            //当日报警总次数
            List<AlarmCar> alarmCarToDayListSum = alarmCarMapper.selectList(queryAlarmCarWrapper2);
            for (AlarmCar alarmCar : alarmCarToDayListSum
            ) {
                alarmCar.setExpType("1");
                alarmCar.setCarNameAndAlarmTypeName(alarmCar.getCarName() + "-" + alarmCar.getAlarmTypeName());
                expCpToDayList.add(alarmCar);
            }

//            int alarmCarToDayListSumCount = Objects.nonNull(alarmCarToDayListSum) && alarmCarToDayListSum.size() > 0 ? alarmCarToDayListSum.size() : 0;
            //当日违规总次数
            List<CarViolation> carViolationToDayListSum = carViolationMapper.selectList(queryCarViolationWrapper2);
            for (CarViolation carViolation : carViolationToDayListSum
            ) {
                AlarmCar alarmCarItem = new AlarmCar();
                alarmCarItem.setCarId(carViolation.getCarId());
                alarmCarItem.setDepId(carViolation.getDepid());
                alarmCarItem.setDepName(carViolation.getDepName());
                alarmCarItem.setAlarmTypeName(carViolation.getRuleTypeName());
                alarmCarItem.setCarName(carViolation.getCarName());
                alarmCarItem.setCarTypeName(carViolation.getCarTypeName());
                alarmCarItem.setExpType("2");
                alarmCarItem.setDealType(carViolation.getDealType());
                alarmCarItem.setCarNameAndAlarmTypeName(carViolation.getCarName() + "-" + carViolation.getRuleTypeName());
                alarmCarItem.setAlarmCarId(carViolation.getCarViolationId());
                alarmCarItem.setCreateTime(carViolation.getCreateTime());
                alarmCarItem.setContent(carViolation.getContent());
                alarmCarItem.setAlarmTypeId(carViolation.getRuleTypeId());
                alarmCarItem.setLng(carViolation.getLng());
                alarmCarItem.setLat(carViolation.getLat());
                alarmCarItem.setAddress(carViolation.getAddress());
                alarmCarItem.setAlarmTime(carViolation.getTime());
                alarmCarItem.setDealRemark(carViolation.getDealRemark());
                alarmCarItem.setCarTypeId(carViolation.getCarTypeId());
                alarmCarItem.setIsKeep(carViolation.getIsKeep());
                alarmCarItem.setDealUid(carViolation.getDealUid());
                alarmCarItem.setAlarmStartTime(carViolation.getViolationStartTime());
                alarmCarItem.setAlarmEndTime(carViolation.getViolationEndTime());
                expCpToDayList.add(alarmCarItem);
            }

//            int carViolationToDayListSumCount = Objects.nonNull(expCpToDayList) && expCpToDayList.size() > 0 ? expCpToDayList.size() : 0;
            //当日异常总次数
            int expCount = Objects.nonNull(expCpToDayList) && expCpToDayList.size() > 0 ? expCpToDayList.size() : 0;
            json.put("expCount", expCount);

            //昨日异常车辆
            List<AlarmCar> expCpYesToDayList = new ArrayList();
            //昨日报警车辆数
            List<AlarmCar> alarmCarYesterdaList = alarmCarMapper.selectList(queryAlarmCarWrapper3);
            for (AlarmCar alarmCar : alarmCarYesterdaList
            ) {
                alarmCar.setExpType("1");
                alarmCar.setCarNameAndAlarmTypeName(alarmCar.getCarName() + "-" + alarmCar.getAlarmTypeName());
                expCpYesToDayList.add(alarmCar);
            }
            //昨日违规车辆数
            List<CarViolation> carViolationYesterdaList = carViolationMapper.selectList(queryCarViolationWrapper3);
            for (CarViolation carViolation : carViolationYesterdaList
            ) {
                AlarmCar alarmCarItem = new AlarmCar();
                alarmCarItem.setCarId(carViolation.getCarId());
                alarmCarItem.setDepId(carViolation.getDepid());
                alarmCarItem.setDepName(carViolation.getDepName());
                alarmCarItem.setAlarmTypeName(carViolation.getRuleTypeName());
                alarmCarItem.setCarName(carViolation.getCarName());
                alarmCarItem.setCarTypeName(carViolation.getCarTypeName());
                alarmCarItem.setExpType("2");
                alarmCarItem.setDealType(carViolation.getDealType());
                alarmCarItem.setCarNameAndAlarmTypeName(carViolation.getCarName() + "-" + carViolation.getRuleTypeName());
                alarmCarItem.setAlarmCarId(carViolation.getCarViolationId());
                alarmCarItem.setCreateTime(carViolation.getCreateTime());
                alarmCarItem.setContent(carViolation.getContent());
                alarmCarItem.setAlarmTypeId(carViolation.getRuleTypeId());
                alarmCarItem.setLng(carViolation.getLng());
                alarmCarItem.setLat(carViolation.getLat());
                alarmCarItem.setAddress(carViolation.getAddress());
                alarmCarItem.setAlarmTime(carViolation.getTime());
                alarmCarItem.setDealRemark(carViolation.getDealRemark());
                alarmCarItem.setCarTypeId(carViolation.getCarTypeId());
                alarmCarItem.setIsKeep(carViolation.getIsKeep());
                alarmCarItem.setDealUid(carViolation.getDealUid());
                alarmCarItem.setAlarmStartTime(carViolation.getViolationStartTime());
                alarmCarItem.setAlarmEndTime(carViolation.getViolationEndTime());
                expCpYesToDayList.add(alarmCarItem);
            }
            Map<String, List<AlarmCar>> abnormalYesToDayByCarIdMap = expCpYesToDayList.stream().collect(Collectors.groupingBy(AlarmCar::getCarId));
            //昨日异常车辆数
            int expCpY = abnormalYesToDayByCarIdMap.size();
            json.put("tbsrCp", expCp - expCpY);

            //昨日报警总次数
            List<AlarmCar> alarmCarYesterdaListSum = alarmCarMapper.selectList(queryAlarmCarWrapper4);
            int alarmCarYesterdaListSumCount = Objects.nonNull(alarmCarYesterdaListSum) && alarmCarYesterdaListSum.size() > 0 ? alarmCarYesterdaListSum.size() : 0;
            //昨日违规总次数
            List<CarViolation> carViolationYesterdaListSum = carViolationMapper.selectList(queryCarViolationWrapper4);
            int carViolationYesterdaListSumCount = Objects.nonNull(carViolationYesterdaListSum) && carViolationYesterdaListSum.size() > 0 ? carViolationYesterdaListSum.size() : 0;
            //昨日异常总次数
            int expCountY = alarmCarYesterdaListSumCount + carViolationYesterdaListSumCount;
            json.put("tbsrCount", expCount - expCountY);

            List groupList = new ArrayList();
            //查询每种异常的数据
            map.put("date", StringUtils.StringToDate3(expListTO.getDate()));
            List<Map> maps1 = alarmCarMapper.alarmCountByTypeName(map);
            Map<String, Long> collect = expCpToDayList.stream().collect(Collectors.groupingBy(AlarmCar::getAlarmTypeName, Collectors.counting()));

            int percentSum = 100;
            collect.keySet().forEach(t -> {
                Map maps = new HashMap<>();
                maps.put("count", collect.get(t));
                maps.put("expName", t);
                if (expCount == 0) {
                    maps.put("percent", 0);
                } else {
                    maps.put("percent", (collect.get(t) * 100) / expCount);
                }
                groupList.add(maps);
            });
            //查询每种违规的数据
            map1.put("date", StringUtils.StringToDate3(expListTO.getDate()));
            List<Map> maps2 = alarmCarMapper.alarmViolationByTypeName(map1);
            for (int i = 0; i < maps2.size(); i++) {
                Map maps = new HashMap<>();
                maps.put("count", Integer.parseInt(maps2.get(0).get("count").toString()));
                maps.put("expName", maps2.get(i).get("expName").toString());
                if (i + 1 == maps2.size()) {
                    maps.put("percent", percentSum);
                } else {
                    if (expCount == 0) {
                        maps.put("percent", 0);
                    } else {
                        maps.put("percent", (Integer.parseInt(maps2.get(0).get("count").toString()) * 100) / expCount);
                        percentSum = percentSum - (Integer.parseInt(maps2.get(0).get("count").toString()) * 100) / expCount;
                    }
                }
                groupList.add(maps);
            }
            json.put("groupList", groupList);

            List<Abnormal> exp = new ArrayList();
            Map<String, List<AlarmCar>> abnormalByCarNameAndAlarmTypeName = expCpToDayList.stream().collect(Collectors.groupingBy(AlarmCar::getCarNameAndAlarmTypeName));
            abnormalByCarNameAndAlarmTypeName.keySet().forEach(k -> {
                Abnormal abnormal = new Abnormal();

                abnormal.setItemId(abnormalByCarNameAndAlarmTypeName.get(k).get(0).getCarId());
                abnormal.setDepName(abnormalByCarNameAndAlarmTypeName.get(k).get(0).getDepName());
                abnormal.setExpName(abnormalByCarNameAndAlarmTypeName.get(k).get(0).getAlarmTypeName());
                abnormal.setName(abnormalByCarNameAndAlarmTypeName.get(k).get(0).getCarName());
                abnormal.setType(abnormalByCarNameAndAlarmTypeName.get(k).get(0).getCarTypeName());
                abnormal.setExpType(abnormalByCarNameAndAlarmTypeName.get(k).get(0).getExpType());

                BigDecimal duration = BigDecimal.ZERO;
                List items = new ArrayList();
                for (AlarmCar alarmCar : abnormalByCarNameAndAlarmTypeName.get(k)
                ) {
                    Map item = new HashMap();
                    item.put("itemId", alarmCar.getAlarmCarId());
                    item.put("content", alarmCar.getContent());
                    item.put("dealType", alarmCar.getDealType());
                    item.put("createTime", alarmCar.getAlarmTime());
                    items.add(item);
                    int s = 0;
                    if (Objects.nonNull(alarmCar.getAlarmStartTime()) && Objects.nonNull(alarmCar.getAlarmEndTime())) {
                        s = StringUtils.calLastedTime(alarmCar.getAlarmStartTime(), alarmCar.getAlarmEndTime());
                    }
                    if (s == 0) {
                        s = 30;
                    }
                    duration = duration.add(new BigDecimal(String.valueOf(s)));

                    if (Objects.isNull(abnormal.getExpTime())) {
                        abnormal.setExpTime(alarmCar.getAlarmTime());
                    } else if (alarmCar.getAlarmTime().compareTo(abnormal.getExpTime()) > 0) {
                        abnormal.setExpTime(alarmCar.getAlarmTime());
                    }
                }
                abnormal.setItems(items);

                abnormal.setDuration(StringUtils.s2date(duration.longValue()));
                exp.add(abnormal);
            });
            //按照异常时间倒序排序
            Collections.sort(exp, (o1, o2) -> {
                Date d1 = o1.getExpTime();
                Date d2 = o2.getExpTime();
                return d2.compareTo(d1);
            });
            json.put("exp", exp);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return json;
    }

    @Override
    public JSONObject expPersonList(ExpListTO expListTO) {
        JSONObject json = new JSONObject();
        try {
            //当日报警人员
            QueryWrapper<AlarmPerson> queryAlarmPersonWrapper = new QueryWrapper<>();
            //当日违规人员
            QueryWrapper<DlbjViolation> queryDlbjViolationWrapper = new QueryWrapper<>();

            //当日报警总次数
            QueryWrapper<AlarmPerson> queryAlarmPersonWrapper2 = new QueryWrapper<>();
            //当日违规总次数
            QueryWrapper<DlbjViolation> queryDlbjViolationWrapper2 = new QueryWrapper<>();

            //昨日异常人员数
            QueryWrapper<AlarmPerson> queryAlarmPersonWrapper3 = new QueryWrapper<>();
            //昨日违规人员数
            QueryWrapper<DlbjViolation> queryDlbjViolationWrapper3 = new QueryWrapper<>();

            //昨日异常总次数
            QueryWrapper<AlarmPerson> queryAlarmPersonWrapper4 = new QueryWrapper<>();
            //昨日异常总次数
            QueryWrapper<DlbjViolation> queryDlbjViolationWrapper4 = new QueryWrapper<>();

            //查询每种异常的数据
            Map map = new HashMap();
            //查询每种违规的数据
            Map map1 = new HashMap();
            //查询该辆车的该报警记录
            QueryWrapper<AlarmPerson> queryAlarmWrapper = new QueryWrapper<>();

            String day = expListTO.getDate();
            String startTime = AttributeUtils.timeCompletion(day, 's');
            String endTime = AttributeUtils.timeCompletion(day, 'e');
            Date date = StringUtils.StringToDate3(day);
            Date date1 = new Date(date.getTime() - 1000 * 60 * 60 * 24);
            String yesToday = StringUtils.dateToStr(date1, "");
            String startTimeYesToday = AttributeUtils.timeCompletion(yesToday, 's');
            String endTimeYesToday = AttributeUtils.timeCompletion(yesToday, 'e');

            if (StringUtils.isNotEmpty(expListTO.getExpName())) {
                queryAlarmPersonWrapper.lambda().eq(AlarmPerson::getAlarmTypeName, expListTO.getExpName());
                queryDlbjViolationWrapper.lambda().eq(DlbjViolation::getViolationTypeName, expListTO.getExpName());
                queryAlarmPersonWrapper2.lambda().eq(AlarmPerson::getAlarmTypeName, expListTO.getExpName());
                queryDlbjViolationWrapper2.lambda().eq(DlbjViolation::getViolationTypeName, expListTO.getExpName());
                queryAlarmPersonWrapper3.lambda().eq(AlarmPerson::getAlarmTypeName, expListTO.getExpName());
                queryDlbjViolationWrapper3.lambda().eq(DlbjViolation::getViolationTypeName, expListTO.getExpName());
                queryAlarmPersonWrapper4.lambda().eq(AlarmPerson::getAlarmTypeName, expListTO.getExpName());
                queryDlbjViolationWrapper4.lambda().eq(DlbjViolation::getViolationTypeName, expListTO.getExpName());
                queryAlarmWrapper.lambda().eq(AlarmPerson::getAlarmTypeName, expListTO.getExpName());
                map.put("expName", expListTO.getExpName());
                map1.put("expName", expListTO.getExpName());
            }
            if (StringUtils.isNotEmpty(expListTO.getType())) {
                queryAlarmPersonWrapper.lambda().eq(AlarmPerson::getPersonTypeName, expListTO.getType());
                queryDlbjViolationWrapper.lambda().eq(DlbjViolation::getPersonTypeName, expListTO.getType());
                queryAlarmPersonWrapper2.lambda().eq(AlarmPerson::getPersonTypeName, expListTO.getType());
                queryDlbjViolationWrapper2.lambda().eq(DlbjViolation::getPersonTypeName, expListTO.getType());
                queryAlarmPersonWrapper3.lambda().eq(AlarmPerson::getPersonTypeName, expListTO.getType());
                queryDlbjViolationWrapper3.lambda().eq(DlbjViolation::getPersonTypeName, expListTO.getType());
                queryAlarmPersonWrapper4.lambda().eq(AlarmPerson::getPersonTypeName, expListTO.getType());
                queryDlbjViolationWrapper4.lambda().eq(DlbjViolation::getPersonTypeName, expListTO.getType());
                queryAlarmWrapper.lambda().eq(AlarmPerson::getPersonTypeName, expListTO.getType());
                map.put("type", expListTO.getType());
                map1.put("type", expListTO.getType());
            }

            queryAlarmPersonWrapper.lambda().between(AlarmPerson::getAlarmTime, startTime, endTime);
            queryAlarmPersonWrapper.lambda().groupBy(AlarmPerson::getPersonId);
            queryAlarmPersonWrapper.lambda().orderByDesc(AlarmPerson::getAlarmTime);
            queryDlbjViolationWrapper.lambda().between(DlbjViolation::getDate, startTime, endTime);
            queryDlbjViolationWrapper.lambda().groupBy(DlbjViolation::getPersonId);
            queryDlbjViolationWrapper.lambda().orderByDesc(DlbjViolation::getDate);
            queryAlarmPersonWrapper2.lambda().between(AlarmPerson::getAlarmTime, startTime, endTime);
            queryAlarmPersonWrapper2.lambda().orderByDesc(AlarmPerson::getAlarmTime);
            queryDlbjViolationWrapper2.lambda().between(DlbjViolation::getDate, startTime, endTime);
            queryDlbjViolationWrapper2.lambda().orderByDesc(DlbjViolation::getDate);
            queryAlarmPersonWrapper3.lambda().between(AlarmPerson::getAlarmTime, startTimeYesToday, endTimeYesToday);
            queryAlarmPersonWrapper3.lambda().groupBy(AlarmPerson::getPersonId);
            queryAlarmPersonWrapper3.lambda().orderByDesc(AlarmPerson::getAlarmTime);
            queryDlbjViolationWrapper3.lambda().between(DlbjViolation::getDate, startTimeYesToday, endTimeYesToday);
            queryDlbjViolationWrapper3.lambda().groupBy(DlbjViolation::getPersonId);
            queryDlbjViolationWrapper3.lambda().orderByDesc(DlbjViolation::getDate);
            queryAlarmPersonWrapper4.lambda().between(AlarmPerson::getAlarmTime, startTimeYesToday, endTimeYesToday);
            queryAlarmPersonWrapper4.lambda().orderByDesc(AlarmPerson::getAlarmTime);
            queryDlbjViolationWrapper4.lambda().between(DlbjViolation::getDate, startTimeYesToday, endTimeYesToday);
            queryDlbjViolationWrapper4.lambda().orderByDesc(DlbjViolation::getDate);

            //当日异常人员
            List<AlarmPerson> expCpList = new ArrayList();
            //当日报警人员
            List<AlarmPerson> alarmPersonToDayList = alarmPersonMapper.selectList(queryAlarmPersonWrapper);
            for (AlarmPerson alarmPerson : alarmPersonToDayList
            ) {
                alarmPerson.setExpType("1");
                alarmPerson.setPersonNameAndAlarmTypeName(alarmPerson.getPersonName() + "-" + alarmPerson.getAlarmTypeName());
                expCpList.add(alarmPerson);
            }
            //当日违规人员
            List<DlbjViolation> dlbjViolationToDayList = dlbjViolationMapper.selectList(queryDlbjViolationWrapper);
            for (DlbjViolation dlbjViolation : dlbjViolationToDayList
            ) {
                AlarmPerson alarmPersonItem = new AlarmPerson();
                alarmPersonItem.setPersonId(dlbjViolation.getPersonId());
                alarmPersonItem.setDepId(dlbjViolation.getDepid());
                alarmPersonItem.setDepName(dlbjViolation.getDepName());
                alarmPersonItem.setAlarmTypeName(dlbjViolation.getViolationTypeName());
                alarmPersonItem.setPersonName(dlbjViolation.getPersonName());
                alarmPersonItem.setPersonTypeName(dlbjViolation.getPersonTypeName());
                alarmPersonItem.setExpType("2");
                alarmPersonItem.setDealType(dlbjViolation.getDealType());
                alarmPersonItem.setPersonNameAndAlarmTypeName(dlbjViolation.getPersonName() + "-" + dlbjViolation.getViolationTypeName());
                alarmPersonItem.setAlarmPersonId(dlbjViolation.getDlbjViolationId());
                alarmPersonItem.setCreateTime(dlbjViolation.getCreateTime());
                alarmPersonItem.setContent(dlbjViolation.getContent());
                alarmPersonItem.setAlarmTypeId(dlbjViolation.getViolationTypeId());
                alarmPersonItem.setLng(dlbjViolation.getLng());
                alarmPersonItem.setLat(dlbjViolation.getLat());
                alarmPersonItem.setAddress(dlbjViolation.getAddress());
                alarmPersonItem.setAlarmTime(dlbjViolation.getDate());
                alarmPersonItem.setDealRemark(dlbjViolation.getDealRemark());
                alarmPersonItem.setPersonTypeId(dlbjViolation.getPersonTypeId());
                alarmPersonItem.setDealUid(dlbjViolation.getDealUid());
                alarmPersonItem.setIsKeep(dlbjViolation.getIsKeep());
                alarmPersonItem.setAlarmStartTime(dlbjViolation.getViolationStartTime());
                alarmPersonItem.setAlarmEndTime(dlbjViolation.getViolationEndTime());
                expCpList.add(alarmPersonItem);
            }
            Map<String, List<AlarmPerson>> abnormalByPersonIdMap = expCpList.stream().collect(Collectors.groupingBy(AlarmPerson::getPersonId));
            //当日异常人员数量
            int expCp = 0;
            if (Objects.nonNull(abnormalByPersonIdMap)) {
                expCp = abnormalByPersonIdMap.size();
            }
            json.put("expCp", expCp);

            //当日异常人员
            List<AlarmPerson> expCpToDayList = new ArrayList();
            //当日报警总次数
            List<AlarmPerson> alarmPersonToDayListSum = alarmPersonMapper.selectList(queryAlarmPersonWrapper2);
            for (AlarmPerson alarmPerson : alarmPersonToDayListSum
            ) {
                alarmPerson.setExpType("1");
                alarmPerson.setPersonNameAndAlarmTypeName(alarmPerson.getPersonName() + "-" + alarmPerson.getAlarmTypeName());
                expCpToDayList.add(alarmPerson);
            }
            //当日违规总次数
            List<DlbjViolation> dlbjViolationToDayListSum = dlbjViolationMapper.selectList(queryDlbjViolationWrapper2);
            for (DlbjViolation dlbjViolation : dlbjViolationToDayListSum
            ) {
                AlarmPerson alarmPersonItem = new AlarmPerson();
                alarmPersonItem.setPersonId(dlbjViolation.getPersonId());
                alarmPersonItem.setDepId(dlbjViolation.getDepid());
                alarmPersonItem.setDepName(dlbjViolation.getDepName());
                alarmPersonItem.setAlarmTypeName(dlbjViolation.getViolationTypeName());
                alarmPersonItem.setPersonName(dlbjViolation.getPersonName());
                alarmPersonItem.setPersonTypeName(dlbjViolation.getPersonTypeName());
                alarmPersonItem.setExpType("2");
                alarmPersonItem.setDealType(dlbjViolation.getDealType());
                alarmPersonItem.setPersonNameAndAlarmTypeName(dlbjViolation.getPersonName() + "-" + dlbjViolation.getViolationTypeName());
                alarmPersonItem.setAlarmPersonId(dlbjViolation.getDlbjViolationId());
                alarmPersonItem.setCreateTime(dlbjViolation.getCreateTime());
                alarmPersonItem.setContent(dlbjViolation.getContent());
                alarmPersonItem.setAlarmTypeId(dlbjViolation.getViolationTypeId());
                alarmPersonItem.setLng(dlbjViolation.getLng());
                alarmPersonItem.setLat(dlbjViolation.getLat());
                alarmPersonItem.setAddress(dlbjViolation.getAddress());
                alarmPersonItem.setAlarmTime(dlbjViolation.getDate());
                alarmPersonItem.setDealRemark(dlbjViolation.getDealRemark());
                alarmPersonItem.setPersonTypeId(dlbjViolation.getPersonTypeId());
                alarmPersonItem.setDealUid(dlbjViolation.getDealUid());
                alarmPersonItem.setIsKeep(dlbjViolation.getIsKeep());
                alarmPersonItem.setAlarmStartTime(dlbjViolation.getViolationStartTime());
                alarmPersonItem.setAlarmEndTime(dlbjViolation.getViolationEndTime());
                expCpToDayList.add(alarmPersonItem);
            }
            //当日异常总次数
            int expCount = Objects.nonNull(expCpToDayList) && expCpToDayList.size() > 0 ? expCpToDayList.size() : 0;
            json.put("expCount", expCount);

            //昨日异常车辆
            List<AlarmPerson> expCpYesToDayList = new ArrayList();
            //昨日报警人员数
            List<AlarmPerson> alarmPersonYesterdaList = alarmPersonMapper.selectList(queryAlarmPersonWrapper3);
            for (AlarmPerson alarmPerson : alarmPersonToDayListSum
            ) {
                alarmPerson.setExpType("1");
                alarmPerson.setPersonNameAndAlarmTypeName(alarmPerson.getPersonName() + "-" + alarmPerson.getAlarmTypeName());
                expCpYesToDayList.add(alarmPerson);
            }
            //昨日违规人员数
            List<DlbjViolation> dlbjViolationYesterdaList = dlbjViolationMapper.selectList(queryDlbjViolationWrapper3);
            for (DlbjViolation dlbjViolation : dlbjViolationToDayListSum
            ) {
                AlarmPerson alarmPersonItem = new AlarmPerson();
                alarmPersonItem.setPersonId(dlbjViolation.getPersonId());
                alarmPersonItem.setDepId(dlbjViolation.getDepid());
                alarmPersonItem.setDepName(dlbjViolation.getDepName());
                alarmPersonItem.setAlarmTypeName(dlbjViolation.getViolationTypeName());
                alarmPersonItem.setPersonName(dlbjViolation.getPersonName());
                alarmPersonItem.setPersonTypeName(dlbjViolation.getPersonTypeName());
                alarmPersonItem.setExpType("2");
                alarmPersonItem.setDealType(dlbjViolation.getDealType());
                alarmPersonItem.setPersonNameAndAlarmTypeName(dlbjViolation.getPersonName() + "-" + dlbjViolation.getViolationTypeName());
                alarmPersonItem.setAlarmPersonId(dlbjViolation.getDlbjViolationId());
                alarmPersonItem.setCreateTime(dlbjViolation.getCreateTime());
                alarmPersonItem.setContent(dlbjViolation.getContent());
                alarmPersonItem.setAlarmTypeId(dlbjViolation.getViolationTypeId());
                alarmPersonItem.setLng(dlbjViolation.getLng());
                alarmPersonItem.setLat(dlbjViolation.getLat());
                alarmPersonItem.setAddress(dlbjViolation.getAddress());
                alarmPersonItem.setAlarmTime(dlbjViolation.getDate());
                alarmPersonItem.setDealRemark(dlbjViolation.getDealRemark());
                alarmPersonItem.setPersonTypeId(dlbjViolation.getPersonTypeId());
                alarmPersonItem.setDealUid(dlbjViolation.getDealUid());
                alarmPersonItem.setIsKeep(dlbjViolation.getIsKeep());
                alarmPersonItem.setAlarmStartTime(dlbjViolation.getViolationStartTime());
                alarmPersonItem.setAlarmEndTime(dlbjViolation.getViolationEndTime());
                expCpYesToDayList.add(alarmPersonItem);
            }
            Map<String, List<AlarmPerson>> abnormalYesToDayByCarIdMap = expCpYesToDayList.stream().collect(Collectors.groupingBy(AlarmPerson::getPersonId));
            //昨日异常车辆数
            int expCpY = abnormalYesToDayByCarIdMap.size();
            json.put("tbsrCp", expCp - expCpY);

            //昨日报警总次数
            List<AlarmPerson> alarmPersonYesterdaListSum = alarmPersonMapper.selectList(queryAlarmPersonWrapper4);
            int alarmPersonYesterdaListSumCount = Objects.nonNull(alarmPersonYesterdaListSum) && alarmPersonYesterdaListSum.size() > 0 ? alarmPersonYesterdaListSum.size() : 0;
            //昨日违规总次数
            List<DlbjViolation> dlbjViolationYesterdaListSum = dlbjViolationMapper.selectList(queryDlbjViolationWrapper4);
            int dlbjViolationYesterdaListSumCount = Objects.nonNull(dlbjViolationYesterdaListSum) && dlbjViolationYesterdaListSum.size() > 0 ? dlbjViolationYesterdaListSum.size() : 0;
            //昨日异常总次数
            int expCountY = alarmPersonYesterdaListSumCount + dlbjViolationYesterdaListSumCount;
            json.put("tbsrCount", expCount - expCountY);

            List groupList = new ArrayList();
            //查询每种异常的数据
            map.put("date", StringUtils.StringToDate3(expListTO.getDate()));
            List<Map> maps1 = alarmPersonMapper.alarmCountByTypeName(map);
            int percentSum = 100;
            for (Map alarm : maps1) {
                Map maps = new HashMap<>();
                maps.put("count", Integer.parseInt(alarm.get("count").toString()));
                maps.put("expName", alarm.get("expName").toString());
                if (expCount == 0) {
                    maps.put("percent", 0);
                } else {
                    maps.put("percent", (Integer.parseInt(alarm.get("count").toString()) * 100) / expCount);
                }
                groupList.add(maps);
            }
            //查询每种违规的数据
            map1.put("date", StringUtils.StringToDate3(expListTO.getDate()));
            List<Map> maps2 = alarmPersonMapper.alarmViolationByTypeName(map1);
            for (int i = 0; i < maps2.size(); i++) {
                Map maps = new HashMap<>();
                maps.put("count", Integer.parseInt(maps2.get(0).get("count").toString()));
                maps.put("expName", maps2.get(i).get("expName").toString());
                if (i + 1 == maps2.size()) {
                    maps.put("percent", percentSum);
                } else {
                    if (expCount == 0) {
                        maps.put("percent", 0);
                    } else {
                        maps.put("percent", (Integer.parseInt(maps2.get(0).get("count").toString()) * 100) / expCount);
                        percentSum = percentSum - (Integer.parseInt(maps2.get(0).get("count").toString()) * 100) / expCount;
                    }
                }
                groupList.add(maps);
            }
            json.put("groupList", groupList);

            List<Abnormal> exp = new ArrayList();
            Map<String, List<AlarmPerson>> abnormalByCarNameAndAlarmTypeName = expCpToDayList.stream().collect(Collectors.groupingBy(AlarmPerson::getPersonNameAndAlarmTypeName));
            abnormalByCarNameAndAlarmTypeName.keySet().forEach(k -> {
                Abnormal abnormal = new Abnormal();

                abnormal.setItemId(abnormalByCarNameAndAlarmTypeName.get(k).get(0).getPersonId());
                abnormal.setDepName(abnormalByCarNameAndAlarmTypeName.get(k).get(0).getDepName());
                abnormal.setExpName(abnormalByCarNameAndAlarmTypeName.get(k).get(0).getAlarmTypeName());
                abnormal.setName(abnormalByCarNameAndAlarmTypeName.get(k).get(0).getPersonName());
                abnormal.setType(abnormalByCarNameAndAlarmTypeName.get(k).get(0).getPersonTypeName());
                abnormal.setExpType(abnormalByCarNameAndAlarmTypeName.get(k).get(0).getExpType());

                BigDecimal duration = BigDecimal.ZERO;
                List items = new ArrayList();
                for (AlarmPerson alarmPerson : abnormalByCarNameAndAlarmTypeName.get(k)
                ) {
                    Map item = new HashMap();
                    item.put("itemId", alarmPerson.getAlarmPersonId());
                    item.put("content", alarmPerson.getContent());
                    item.put("dealType", alarmPerson.getDealType());
                    item.put("createTime", alarmPerson.getAlarmTime());
                    items.add(item);
                    int s = 0;
                    if (Objects.nonNull(alarmPerson.getAlarmStartTime()) && Objects.nonNull(alarmPerson.getAlarmEndTime())) {
                        s = StringUtils.calLastedTime(alarmPerson.getAlarmStartTime(), alarmPerson.getAlarmEndTime());
                    }
                    if (s == 0) {
                        s = 30;
                    }
                    duration = duration.add(new BigDecimal(String.valueOf(s)));

                    if (Objects.isNull(abnormal.getExpTime())) {
                        abnormal.setExpTime(alarmPerson.getAlarmTime());
                    } else if (alarmPerson.getAlarmTime().compareTo(abnormal.getExpTime()) > 0) {
                        abnormal.setExpTime(alarmPerson.getAlarmTime());
                    }
                }
                abnormal.setItems(items);
                abnormal.setDuration(StringUtils.s2date(duration.longValue()));
                exp.add(abnormal);
            });
            //按照异常时间倒序排序
            Collections.sort(exp, (o1, o2) -> {
                Date d1 = o1.getExpTime();
                Date d2 = o2.getExpTime();
                return d2.compareTo(d1);
            });
            json.put("exp", exp);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return json;
    }

    @Override
    public JSONObject expFacilitiesList(ExpListTO expListTO) {
        JSONObject json = new JSONObject();
        try {
            //当日报警设施
            QueryWrapper<AlarmSheshi> queryAlarmSheshiWrapper = new QueryWrapper<>();

            //当日报警总次数
            QueryWrapper<AlarmSheshi> queryAlarmSheshiWrapper2 = new QueryWrapper<>();

            //昨日异常设施数
            QueryWrapper<AlarmSheshi> queryAlarmSheshiWrapper3 = new QueryWrapper<>();

            //昨日异常总次数
            QueryWrapper<AlarmSheshi> queryAlarmSheshiWrapper4 = new QueryWrapper<>();

            //查询每种异常的数据
            Map map = new HashMap();
            //查询该设施的该报警记录
            QueryWrapper<AlarmSheshi> queryAlarmWrapper = new QueryWrapper<>();

            String day = expListTO.getDate();
            String startTime = AttributeUtils.timeCompletion(day, 's');
            String endTime = AttributeUtils.timeCompletion(day, 'e');
            Date date = StringUtils.StringToDate3(day);
            Date date1 = new Date(date.getTime() - 1000 * 60 * 60 * 24);
            String yesToday = StringUtils.dateToStr(date1, "");
            String startTimeYesToday = AttributeUtils.timeCompletion(yesToday, 's');
            String endTimeYesToday = AttributeUtils.timeCompletion(yesToday, 'e');

            queryAlarmSheshiWrapper.lambda().eq(AlarmSheshi::getFacltypeid, expListTO.getMaxTypeId());
            queryAlarmSheshiWrapper2.lambda().eq(AlarmSheshi::getFacltypeid, expListTO.getMaxTypeId());
            queryAlarmSheshiWrapper3.lambda().eq(AlarmSheshi::getFacltypeid, expListTO.getMaxTypeId());
            queryAlarmSheshiWrapper4.lambda().eq(AlarmSheshi::getFacltypeid, expListTO.getMaxTypeId());
            queryAlarmWrapper.lambda().eq(AlarmSheshi::getFacltypeid, expListTO.getMaxTypeId());
            map.put("maxTypeId", expListTO.getMaxTypeId());
            if (StringUtils.isNotEmpty(expListTO.getExpName())) {
                queryAlarmSheshiWrapper.lambda().eq(AlarmSheshi::getAlarmTypeName, expListTO.getExpName());
                queryAlarmSheshiWrapper2.lambda().eq(AlarmSheshi::getAlarmTypeName, expListTO.getExpName());
                queryAlarmSheshiWrapper3.lambda().eq(AlarmSheshi::getAlarmTypeName, expListTO.getExpName());
                queryAlarmSheshiWrapper4.lambda().eq(AlarmSheshi::getAlarmTypeName, expListTO.getExpName());
                queryAlarmWrapper.lambda().eq(AlarmSheshi::getAlarmTypeName, expListTO.getExpName());
                map.put("expName", expListTO.getExpName());
            }
            if (StringUtils.isNotEmpty(expListTO.getTypeId())) {
                queryAlarmSheshiWrapper.lambda().eq(AlarmSheshi::getFacltypeitemid, expListTO.getTypeId());
                queryAlarmSheshiWrapper2.lambda().eq(AlarmSheshi::getFacltypeitemid, expListTO.getTypeId());
                queryAlarmSheshiWrapper3.lambda().eq(AlarmSheshi::getFacltypeitemid, expListTO.getTypeId());
                queryAlarmSheshiWrapper4.lambda().eq(AlarmSheshi::getFacltypeitemid, expListTO.getTypeId());
                queryAlarmWrapper.lambda().eq(AlarmSheshi::getFacltypeitemid, expListTO.getTypeId());
                map.put("typeId", expListTO.getTypeId());
            }

            queryAlarmSheshiWrapper.lambda().between(AlarmSheshi::getAlarmTime, startTime, endTime);
            queryAlarmSheshiWrapper.lambda().groupBy(AlarmSheshi::getSheshiId);
            queryAlarmSheshiWrapper.lambda().orderByDesc(AlarmSheshi::getAlarmTime);
            queryAlarmSheshiWrapper2.lambda().between(AlarmSheshi::getAlarmTime, startTime, endTime);
            queryAlarmSheshiWrapper2.lambda().orderByDesc(AlarmSheshi::getAlarmTime);
            queryAlarmSheshiWrapper3.lambda().between(AlarmSheshi::getAlarmTime, startTimeYesToday, endTimeYesToday);
            queryAlarmSheshiWrapper3.lambda().groupBy(AlarmSheshi::getSheshiId);
            queryAlarmSheshiWrapper3.lambda().orderByDesc(AlarmSheshi::getAlarmTime);
            queryAlarmSheshiWrapper4.lambda().between(AlarmSheshi::getAlarmTime, startTimeYesToday, endTimeYesToday);
            queryAlarmSheshiWrapper4.lambda().orderByDesc(AlarmSheshi::getAlarmTime);

            //当日异常设施数量
            List<AlarmSheshi> expCpTodayList = alarmSheshiMapper.selectList(queryAlarmSheshiWrapper);
            int expCp = 0;
            if (Objects.nonNull(expCpTodayList)) {
                expCp = expCpTodayList.size();
            }
            json.put("expCp", expCp);
            List<AlarmSheshi> expCpList = new ArrayList<>();
            //当日异常总次数
            List<AlarmSheshi> expCountList = alarmSheshiMapper.selectList(queryAlarmSheshiWrapper2);
            for (AlarmSheshi alarmSheshi : expCountList
            ) {
                alarmSheshi.setSheshiNameAndAlarmTypeName(alarmSheshi.getSheshiId() + "-" + alarmSheshi.getAlarmTypeId());
                expCpList.add(alarmSheshi);
            }
            int expCount = 0;
            if (Objects.nonNull(expCountList)) {
                expCount = expCountList.size();
            }
            json.put("expCount", expCount);

            //昨日报警设施数
            List<AlarmSheshi> expCpYList = alarmSheshiMapper.selectList(queryAlarmSheshiWrapper3);
            int expCpY = 0;
            if (Objects.nonNull(expCpYList)) {
                expCpY = expCpYList.size();
            }
            json.put("tbsrCp", expCp - expCpY);

            //昨日异常总次数
            List<AlarmSheshi> expCountYList = alarmSheshiMapper.selectList(queryAlarmSheshiWrapper4);
            int expCountY = 0;
            if (Objects.nonNull(expCountYList)) {
                expCountY = expCountYList.size();
            }
            json.put("tbsrCount", expCount - expCountY);

            List groupList = new ArrayList();
            //查询每种异常的数据
            map.put("date", StringUtils.StringToDate3(expListTO.getDate()));
            List<Map> maps1 = alarmSheshiMapper.alarmCountByTypeId(map);
            int percentSum = 100;
            for (int i = 0; i < maps1.size(); i++) {
                Map maps = new HashMap<>();
                if (Objects.nonNull(maps1.get(i).get("count")) && Objects.nonNull(maps1.get(i).get("expName"))) {
                    maps.put("expName", String.valueOf(maps1.get(i).get("expName")));
                    maps.put("count", Integer.parseInt(String.valueOf(maps1.get(i).get("count"))));
                    if (Integer.parseInt(String.valueOf(maps1.get(i).get("count"))) * 100 == 0 || expCount == 0) {
                        maps.put("percent", 0);
                    } else {
                        if (i + 1 == maps1.size()) {
                            maps.put("percent", percentSum);
                        } else {
                            if (expCount == 0) {
                                maps.put("percent", 0);
                            } else {
                                maps.put("percent", (Integer.parseInt(String.valueOf(maps1.get(i).get("count"))) * 100) / expCount);
                                percentSum = percentSum - (Integer.parseInt(String.valueOf(maps1.get(i).get("count"))) * 100) / expCount;
                            }
                        }
                    }
                }
                groupList.add(maps);
            }

            json.put("groupList", groupList);

            List<Abnormal> exp = new ArrayList();
            Map<String, List<AlarmSheshi>> abnormalByCarNameAndAlarmTypeName = expCpList.stream().collect(Collectors.groupingBy(AlarmSheshi::getSheshiNameAndAlarmTypeName));
            abnormalByCarNameAndAlarmTypeName.keySet().forEach(k -> {
                Abnormal abnormal = new Abnormal();

                abnormal.setItemId(abnormalByCarNameAndAlarmTypeName.get(k).get(0).getSheshiId());
                abnormal.setDepName(abnormalByCarNameAndAlarmTypeName.get(k).get(0).getDepName());
                abnormal.setExpName(abnormalByCarNameAndAlarmTypeName.get(k).get(0).getAlarmTypeName());
                abnormal.setName(abnormalByCarNameAndAlarmTypeName.get(k).get(0).getSheshiName());
                abnormal.setType(abnormalByCarNameAndAlarmTypeName.get(k).get(0).getFacltypeitemname());
                abnormal.setExpType("0");

                BigDecimal duration = BigDecimal.ZERO;
                List items = new ArrayList();
                for (AlarmSheshi alarmSheshi : abnormalByCarNameAndAlarmTypeName.get(k)
                ) {
                    Map item = new HashMap();
                    item.put("itemId", alarmSheshi.getAlarmSheshiId());
                    item.put("content", alarmSheshi.getContent());
                    item.put("dealType", alarmSheshi.getDealType());
                    item.put("createTime", alarmSheshi.getAlarmTime());
                    items.add(item);
                    int s = 0;
                    if (Objects.nonNull(alarmSheshi.getAlarmStartTime()) && Objects.nonNull(alarmSheshi.getAlarmEndTime())) {
                        s = StringUtils.calLastedTime(alarmSheshi.getAlarmStartTime(), alarmSheshi.getAlarmEndTime());
                    }
                    if (s == 0) {
                        s = 3;
                    }
                    duration = duration.add(new BigDecimal(String.valueOf(s)));

                    if (Objects.isNull(abnormal.getExpTime())) {
                        abnormal.setExpTime(alarmSheshi.getAlarmTime());
                    } else if (alarmSheshi.getAlarmTime().compareTo(abnormal.getExpTime()) > 0) {
                        abnormal.setExpTime(alarmSheshi.getAlarmTime());
                    }
                }
                abnormal.setItems(items);
                abnormal.setDuration(StringUtils.s2date(duration.longValue()));
                exp.add(abnormal);
            });
            //按照异常时间倒序排序
            Collections.sort(exp, (o1, o2) -> {
                Date d1 = o1.getExpTime();
                Date d2 = o2.getExpTime();
                return d2.compareTo(d1);
            });
            json.put("exp", exp);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return json;
    }

    @Override
    public JSONObject todayException() {
        JSONObject json = new JSONObject();
        //当日报警车辆
        QueryWrapper<AlarmCar> queryAlarmCarWrapper = new QueryWrapper<>();
        //当日违规车辆
        QueryWrapper<CarViolation> queryCarViolationWrapper = new QueryWrapper<>();

        String toDay = DateUtil.formatDate(new Date());
        String startTime = AttributeUtils.timeCompletion(toDay, 's');
        String endTime = AttributeUtils.timeCompletion(toDay, 'e');

        queryAlarmCarWrapper.lambda().between(AlarmCar::getAlarmTime, startTime, endTime);
//        queryAlarmCarWrapper.lambda().groupBy(AlarmCar::getCarId);
        queryAlarmCarWrapper.lambda().orderByDesc(AlarmCar::getAlarmTime);
        queryCarViolationWrapper.lambda().between(CarViolation::getTime, startTime, endTime);
//        queryCarViolationWrapper.lambda().groupBy(CarViolation::getCarId);
        queryCarViolationWrapper.lambda().orderByDesc(CarViolation::getTime);

        //当日异常车辆
        List<AlarmCar> expCpList = new ArrayList();
        //当日报警车辆
        List<AlarmCar> alarmCarToDayList = alarmCarMapper.selectList(queryAlarmCarWrapper);
        for (AlarmCar alarmCar : alarmCarToDayList
        ) {
            alarmCar.setExpType("1");
            alarmCar.setCarNameAndAlarmTypeName(alarmCar.getCarName() + "-" + alarmCar.getAlarmTypeName());
            expCpList.add(alarmCar);
        }
        //当日违规车辆
        List<CarViolation> carViolationToDayList = carViolationMapper.selectList(queryCarViolationWrapper);
        for (CarViolation carViolation : carViolationToDayList
        ) {
            AlarmCar alarmCarItem = new AlarmCar();
            alarmCarItem.setCarId(carViolation.getCarId());
            alarmCarItem.setDepId(carViolation.getDepid());
            alarmCarItem.setDepName(carViolation.getDepName());
            alarmCarItem.setAlarmTypeName(carViolation.getRuleTypeName());
            alarmCarItem.setCarName(carViolation.getCarName());
            alarmCarItem.setCarTypeName(carViolation.getCarTypeName());
            alarmCarItem.setExpType("2");
            alarmCarItem.setDealType(carViolation.getDealType());
            alarmCarItem.setCarNameAndAlarmTypeName(carViolation.getCarName() + "-" + carViolation.getRuleTypeName());
            alarmCarItem.setAlarmCarId(carViolation.getCarViolationId());
            alarmCarItem.setCreateTime(carViolation.getCreateTime());
            alarmCarItem.setContent(carViolation.getContent());
            alarmCarItem.setAlarmTypeId(carViolation.getRuleTypeId());
            alarmCarItem.setLng(carViolation.getLng());
            alarmCarItem.setLat(carViolation.getLat());
            alarmCarItem.setAddress(carViolation.getAddress());
            alarmCarItem.setAlarmTime(carViolation.getTime());
            alarmCarItem.setDealRemark(carViolation.getDealRemark());
            alarmCarItem.setCarTypeId(carViolation.getCarTypeId());
            alarmCarItem.setIsKeep(carViolation.getIsKeep());
            alarmCarItem.setDealUid(carViolation.getDealUid());
            alarmCarItem.setAlarmStartTime(carViolation.getViolationStartTime());
            alarmCarItem.setAlarmEndTime(carViolation.getViolationEndTime());
            expCpList.add(alarmCarItem);
        }
        Map<String, List<AlarmCar>> abnormalByCarIdMap = expCpList.stream().collect(Collectors.groupingBy(AlarmCar::getCarId));
        //当日异常车辆数量
        int expCp = 0;
        if (Objects.nonNull(abnormalByCarIdMap)) {
            expCp = abnormalByCarIdMap.size();
        }


        //当日报警人员
        QueryWrapper<AlarmPerson> queryAlarmPersonWrapper = new QueryWrapper<>();
        //当日违规人员
        QueryWrapper<DlbjViolation> queryDlbjViolationWrapper = new QueryWrapper<>();

        queryAlarmPersonWrapper.lambda().between(AlarmPerson::getAlarmTime, startTime, endTime);
//        queryAlarmPersonWrapper.lambda().groupBy(AlarmPerson::getPersonId);
        queryAlarmPersonWrapper.lambda().orderByDesc(AlarmPerson::getAlarmTime);
        queryDlbjViolationWrapper.lambda().between(DlbjViolation::getDate, startTime, endTime);
//        queryDlbjViolationWrapper.lambda().groupBy(DlbjViolation::getPersonId);
        queryDlbjViolationWrapper.lambda().orderByDesc(DlbjViolation::getDate);

        //当日异常人员
        List<AlarmPerson> expPersonList = new ArrayList();
        //当日报警人员
        List<AlarmPerson> alarmPersonToDayList = alarmPersonMapper.selectList(queryAlarmPersonWrapper);
        for (AlarmPerson alarmPerson : alarmPersonToDayList
        ) {
            alarmPerson.setExpType("1");
            alarmPerson.setPersonNameAndAlarmTypeName(alarmPerson.getPersonName() + "-" + alarmPerson.getAlarmTypeName());
            expPersonList.add(alarmPerson);
        }
        //当日违规人员
        List<DlbjViolation> dlbjViolationToDayList = dlbjViolationMapper.selectList(queryDlbjViolationWrapper);
        for (DlbjViolation dlbjViolation : dlbjViolationToDayList
        ) {
            AlarmPerson alarmPersonItem = new AlarmPerson();
            alarmPersonItem.setPersonId(dlbjViolation.getPersonId());
            alarmPersonItem.setDepId(dlbjViolation.getDepid());
            alarmPersonItem.setDepName(dlbjViolation.getDepName());
            alarmPersonItem.setAlarmTypeName(dlbjViolation.getViolationTypeName());
            alarmPersonItem.setPersonName(dlbjViolation.getPersonName());
            alarmPersonItem.setPersonTypeName(dlbjViolation.getPersonTypeName());
            alarmPersonItem.setExpType("2");
            alarmPersonItem.setDealType(dlbjViolation.getDealType());
            alarmPersonItem.setPersonNameAndAlarmTypeName(dlbjViolation.getPersonName() + "-" + dlbjViolation.getViolationTypeName());
            alarmPersonItem.setAlarmPersonId(dlbjViolation.getDlbjViolationId());
            alarmPersonItem.setCreateTime(dlbjViolation.getCreateTime());
            alarmPersonItem.setContent(dlbjViolation.getContent());
            alarmPersonItem.setAlarmTypeId(dlbjViolation.getViolationTypeId());
            alarmPersonItem.setLng(dlbjViolation.getLng());
            alarmPersonItem.setLat(dlbjViolation.getLat());
            alarmPersonItem.setAddress(dlbjViolation.getAddress());
            alarmPersonItem.setAlarmTime(dlbjViolation.getDate());
            alarmPersonItem.setDealRemark(dlbjViolation.getDealRemark());
            alarmPersonItem.setPersonTypeId(dlbjViolation.getPersonTypeId());
            alarmPersonItem.setDealUid(dlbjViolation.getDealUid());
            alarmPersonItem.setIsKeep(dlbjViolation.getIsKeep());
            alarmPersonItem.setAlarmStartTime(dlbjViolation.getViolationStartTime());
            alarmPersonItem.setAlarmEndTime(dlbjViolation.getViolationEndTime());
            expPersonList.add(alarmPersonItem);
        }
        Map<String, List<AlarmPerson>> abnormalByPersonIdMap = expPersonList.stream().collect(Collectors.groupingBy(AlarmPerson::getPersonId));
        //当日异常人员数量
        int expPerson = 0;
        if (Objects.nonNull(abnormalByPersonIdMap)) {
            expPerson = abnormalByPersonIdMap.size();
        }

        json.put("expPersonCount", expPerson);
        json.put("expCarCount", expCp);

        return json;
    }

    @Override
    public List<JxqsKaoQin> jxzyWorkSceneList(JSONObject params) throws HssException {

        List<JxqsKaoQin> jxqsKaoQinList = new ArrayList();
        QueryWrapper<WorkKaoqin> workKaoqinQueryWrapper = new QueryWrapper<>();
        String date = DateUtil.formatDate(new Date());
        if (StringUtils.isNotEmpty(date)) {
            params.put("startDate", StringUtils.dateToStr(new Date(), "yyyy-MM-dd"));
            params.put("endDate", StringUtils.dateToStr(new Date(), "yyyy-MM-dd"));
        }
        List<WorkKaoqin> workKaoqinList = workKaoqinMapper.selectList(workKaoqinQueryWrapper);
        //关联查询排班和网格
        List<RptCarWork> rptCarWorkList = bigScreenMapper.getJxqsWorkSceneList(params);
        //关联查询人员和车辆
        List<RptCarWork> jxzyWorkDetailList = bigScreenMapper.jxzyWorkDetail(params);
        Jobset jobset = jobsetMapper.selectById("3");
        for (RptCarWork rptCarWork : rptCarWorkList) {
            JxqsKaoQin jxqsKaoQin = new JxqsKaoQin();
            jxqsKaoQin.setJxzyWorkDetaiFilter(new ArrayList<>());
            jxqsKaoQin.setKaoQinId(rptCarWork.getShiftId());
            jxqsKaoQin.setRptCarWork(rptCarWork);
            List<WorkKaoqin> workKaoqinListFilter = workKaoqinList.stream().filter(t -> t.getWorkKaoqinId().equals(rptCarWork.getShiftId())).collect(Collectors.toList());
            if (workKaoqinListFilter.size() > 0) {
                jxqsKaoQin.setWorkKaoqin(workKaoqinListFilter.get(0));
            }
            List<RptCarWork> list1 = jxzyWorkDetailList.stream().filter(t -> t.getPlanId() != null && t.getPlanId().equals(rptCarWork.getPlanId())).collect(Collectors.toList());
            List<RptCarWork> list2 = list1.stream().filter(t -> t.getShiftId().equals(rptCarWork.getShiftId())).collect(Collectors.toList());
            int totalTangci = 0;
            for (int i = 0; i < list2.size(); i++) {
                RptCarWork t = list2.get(i);
                // 把车推进去
                // 单程距离
                //总里程  除以 趟次  每趟里程 //2000
                BigDecimal singleProgress = (t.getTangCi() == null || t.getTangCi() == 0) ? BigDecimal.ZERO : new BigDecimal(t.getAllProgress()).divide(new BigDecimal(t.getTangCi()), BigDecimal.ROUND_HALF_UP);
                // 单程需完成距离
                if (null != jobset) {
                    //每趟里程  乘以 里程完成率阀值 %  // 2000 * 0.7  1400
                    BigDecimal requireSingleProgress = new BigDecimal(jobset.getKmOkThreshold()).multiply(singleProgress).divide(new BigDecimal(100), BigDecimal.ROUND_HALF_UP);
                    // 现里程  除以    requireSingleProgress  得到完成了几趟  4000/1400

                    int thisTangci = (requireSingleProgress == null || requireSingleProgress.equals(BigDecimal.ZERO)) ? 0 : (null == t.getWorkMileage() ? BigDecimal.ZERO : t.getWorkMileage()).divide(requireSingleProgress, BigDecimal.ROUND_FLOOR).intValue();
                    if (null == rptCarWork.getTangCi()) {
                        rptCarWork.setTangCi(0);
                    }
                    if (thisTangci > rptCarWork.getTangCi()) {
                        thisTangci = rptCarWork.getTangCi();
                    }
                    t.setFinishTangci(thisTangci);
                    jxqsKaoQin.getJxzyWorkDetaiFilter().add(t);
                    // 计算总完成趟次
                    totalTangci += thisTangci;
                }
            }
            int rate = 0;
            if (0 != rptCarWork.getTangCi()) {
                rate = rptCarWork.getTangCi() == null || rptCarWork.getTangCi() == 0 ? 0 : totalTangci * 100 / rptCarWork.getTangCi();
//                rate = getRandomNumberInRange(1, 100);
                if (rate >= 100) {
                    rate = 100;
                }
            }
            jxqsKaoQin.setRate(rate);
            jxqsKaoQinList.add(jxqsKaoQin);

        }
        //根据完成度排序
        Collections.sort(jxqsKaoQinList, new Comparator<JxqsKaoQin>() {
            public int compare(JxqsKaoQin o1, JxqsKaoQin o2) {
                Integer rate1 = Integer.valueOf(o1.getRate());
                Integer rate2 = Integer.valueOf(o2.getRate());
                return rate2.compareTo(rate1);
            }
        });

        //驾驶员姓名  车牌号  车辆类型 网格名称 车辆id
        return jxqsKaoQinList;
    }

    @Override
    public List<RptCarWork> jxzyWorkDetail(JSONObject params) throws HssException {

        List<RptCarWork> rptCarWorkList = bigScreenMapper.jxzyWorkDetail(params);
        return rptCarWorkList;
    }

    @Override
    public JSONObject jxzyWorkScene(JSONObject params) throws HssException {

        Date date = new Date();
        String now = DateUtil.formatDate(date);
        // 作业类型：2机械清扫；3垃圾清运；4垃圾转运
        // 状态：0未开始；1进行中；2已结束
        Map<Object, Object> jxqsMap = new HashMap<>();
        jxqsMap.put("workType", 2);
        jxqsMap.put("workDate", now);
        List<RptCarWork> jxqsResultList = rptCarWorkMapper.listByPlan(jxqsMap);

        Integer totalCount = jxqsResultList.size();
        Integer waitingCount = (int) jxqsResultList.stream().filter(t -> t.getAllStatus() == 0).count();
        Integer workingCount = (int) jxqsResultList.stream().filter(t -> t.getAllStatus() == 1).count();
        Integer finishCount = (int) jxqsResultList.stream().filter(t -> t.getAllStatus() == 3).count();
        System.out.println("=====================");
        // 清掃
        int totalCountQs = (int) jxqsResultList.stream().filter(t -> "清扫作业".equals(t.getWorkTypeName())).count();
        int finishCountQs = (int) jxqsResultList.stream().filter(t -> "清扫作业".equals(t.getWorkTypeName())).filter(t1 -> t1.getAllStatus() == 3).count();
        BigDecimal finishRateQs = (finishCountQs == 0) ? BigDecimal.ZERO : (new BigDecimal(finishCountQs).divide(new BigDecimal(totalCountQs), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP));
        // 灑水
        int totalCountSs = (int) jxqsResultList.stream().filter(t -> "洒水作业".equals(t.getWorkTypeName())).count();
        int finishCountSs = (int) jxqsResultList.stream().filter(t -> "洒水作业".equals(t.getWorkTypeName())).filter(t1 -> t1.getAllStatus() == 3).count();
        BigDecimal finishRateSs = (finishCountSs == 0) ? BigDecimal.ZERO : (new BigDecimal(finishCountSs).divide(new BigDecimal(totalCountSs), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP));

        // 汇总
        BigDecimal finishRateTotal = (finishCountQs + finishCountSs == 0) ? BigDecimal.ZERO : (new BigDecimal(finishCountQs + finishCountSs).divide(new BigDecimal(totalCountQs + totalCountSs), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP));


        JSONObject json = new JSONObject();

        json.put("total", totalCount);
        json.put("finished", finishCount);
        json.put("working", workingCount);
        json.put("other", waitingCount);
        json.put("qszyFinishRate", finishRateQs);
        json.put("sszyFinishRate", finishRateSs);
        json.put("totalFinishRate", finishRateTotal);
        return json;
    }


    @Override
    public List<JxqsWorkPlan> getJxqsWorkByCar(JSONObject params) throws HssException {

        return bigScreenMapper.getJxqsWorkByCar(params);
    }

    @Override
    public JSONObject ljqyWorkScene() throws HssException {

        String now = DateUtil.formatDate(new Date());
        // 作业类型：2机械清扫；3垃圾清运；4垃圾转运
        // 状态：0未开始；1进行中；2已结束
        QueryWrapper<RptCarWork> carWorkQueryWrapper = new QueryWrapper<>();
        carWorkQueryWrapper.lambda().eq(RptCarWork::getWorkDate, now);
        carWorkQueryWrapper.lambda().eq(RptCarWork::getWorkType, 3);
        List<RptCarWork> rptCarWorkList = rptCarWorkMapper.selectList(carWorkQueryWrapper);
        //未开始数
        Integer ljqyResultOther = 0;
        //进行数
        Integer ljqyResultWorking = 0;
        //未完成数
        Integer ljqyResultUnfinished = 0;
        //完成数
        Integer ljqyResultFinish = 0;
        List<String> carIds = new ArrayList<>();
        for (RptCarWork rptCarWork : rptCarWorkList) {
            if (0 == rptCarWork.getStatus()) {
                ljqyResultOther++;
            } else if (1 == rptCarWork.getStatus()) {
                ljqyResultWorking++;
            } else if (2 == rptCarWork.getStatus()) {
                ljqyResultUnfinished++;
            } else if (3 == rptCarWork.getStatus()) {
                ljqyResultFinish++;
            }
            carIds.add(rptCarWork.getCarId());
        }
        JSONObject json = new JSONObject();

        //清运计划比
        BigDecimal finishRate = BigDecimal.ZERO;
        BigDecimal mileageSum = BigDecimal.ZERO;
        if (!carIds.isEmpty()) {
            //查询清运人员轨迹
            QueryWrapper<CarTrack> carTrackQueryWrapper = new QueryWrapper<>();
            carTrackQueryWrapper.lambda().orderByAsc(CarTrack::getTimestamp);
            carTrackQueryWrapper.lambda().eq(CarTrack::getWorkDay, LocalDate.now());
            carTrackQueryWrapper.lambda().in(CarTrack::getCarId, carIds);
            List<CarTrack> carTrackList = carTrackMapper.selectList(carTrackQueryWrapper);
            Map<String, List<CarTrack>> map = carTrackList.stream().collect(Collectors.groupingBy(CarTrack::getCarId));
            for (String carId : map.keySet()) {
                for (int i = 0; i < map.get(carId).size(); i++) {
                    if (i > 0) {
                        mileageSum = MathUtils.getBigDecimal(locationUtil.getDistance(map.get(carId).get(i - 1).getLat(), map.get(carId).get(i - 1).getLng(), map.get(carId).get(i).getLat(), map.get(carId).get(i).getLng())).add(mileageSum);
                    }
                }
            }
            Integer totalNumber = ljqyResultWorking + ljqyResultOther + ljqyResultFinish + ljqyResultUnfinished;
            if (0 != totalNumber) {
                finishRate = (new BigDecimal(ljqyResultFinish).divide(new BigDecimal(totalNumber), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100))).setScale(0, BigDecimal.ROUND_UP);
            }
        }
        json.put("unFinished", ljqyResultUnfinished);
        json.put("finished", ljqyResultFinish);
        json.put("working", ljqyResultWorking);
        json.put("other", ljqyResultOther);
        json.put("finishRate", finishRate);
        json.put("mileageSum", mileageSum.divide(new BigDecimal(1000), 0, BigDecimal.ROUND_HALF_UP));
        return json;
    }

    @Override
    public ToDayAttendanceVo  toDayAttendance() {
        ToDayAttendanceVo toDayAttendanceVo = new ToDayAttendanceVo();
        Set<String> todayPlanList = new HashSet<>();
        Integer isNoWorkNumber = 0;
        Integer lateAndLeaveEarlyNumber = 0;
        Integer normalAttendanceNumber = 0;
        Integer leaveNumber = 0;
        Set<String> completeList = new HashSet<>();
        Set<String> workIngList = new HashSet<>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        QueryWrapper<RptEmployeeWork> rptEmployeeWorkQueryWrapper = new QueryWrapper<>();
        rptEmployeeWorkQueryWrapper.lambda().eq(RptEmployeeWork::getWorkDate, dateFormat.format(new Date()));
        List<RptEmployeeWork> rptEmployeeWorkList = rptEmployeeWorkMapper.selectList(rptEmployeeWorkQueryWrapper);
        QueryWrapper<EmployeePunchCard> employeePunchCardQueryWrapper = new QueryWrapper<>();
        employeePunchCardQueryWrapper.lambda().eq(EmployeePunchCard::getPunchCardDate, dateFormat.format(new Date()));
        List<EmployeePunchCard> employeePunchCardList = employeePunchCardMapper.selectList(employeePunchCardQueryWrapper);
        Map<String, List<EmployeePunchCard>> employeePunchCardMap = employeePunchCardList.stream().collect(Collectors.groupingBy(EmployeePunchCard::getEmployeeId));
        for (RptEmployeeWork rptEmployeeWork : rptEmployeeWorkList) {
            todayPlanList.add(rptEmployeeWork.getPlanId());
            if (null != rptEmployeeWork.getStatus()) {
                if (rptEmployeeWork.getStatus() == 3) {
                    completeList.add(rptEmployeeWork.getPlanId());
                }
                if (rptEmployeeWork.getStatus() == 1) {
                    workIngList.add(rptEmployeeWork.getPlanId());
                }
            }
            List<EmployeePunchCard> employeePunchCardList1 = employeePunchCardMap.get(rptEmployeeWork.getEmployeeId());
            if (null != employeePunchCardList1) {
                for (EmployeePunchCard employeePunchCard : employeePunchCardList1) {
                    if (StringUtils.isNotEmpty(employeePunchCard.getNoWork()) && employeePunchCard.getNoWork() == 1) {
                        isNoWorkNumber++;
                    }
                    if (StringUtils.isNotEmpty(employeePunchCard.getLaterIn()) && StringUtils.isNotEmpty(employeePunchCard.getLeaveEarly())) {
                        if (employeePunchCard.getLaterIn() == 1 || employeePunchCard.getLeaveEarly() == 1) {
                            lateAndLeaveEarlyNumber++;
                        }
                    }
                    if (StringUtils.isNotEmpty(employeePunchCard.getNoWork()) && StringUtils.isNotEmpty(employeePunchCard.getLaterIn()) && StringUtils.isNotEmpty(employeePunchCard.getLeaveEarly()) && StringUtils.isNotEmpty(employeePunchCard.getLackCard())) {
                        if (employeePunchCard.getNoWork() == 0 && employeePunchCard.getLaterIn() == 0 && employeePunchCard.getLeaveEarly() == 0 && employeePunchCard.getLackCard() == 0) {
                            normalAttendanceNumber++;
                        }
                    }

                }
            }
        }
        toDayAttendanceVo.setTodayPlanNumber(todayPlanList.size());
        toDayAttendanceVo.setIsNoWorkNumber(isNoWorkNumber); //旷工isNoWork
        toDayAttendanceVo.setLateAndLeaveEarlyNumber(lateAndLeaveEarlyNumber);//迟到和早退lateAndLeaveEarly
        toDayAttendanceVo.setNormalAttendanceNumber(normalAttendanceNumber); //正常出勤 normalAttendance
        toDayAttendanceVo.setLeaveNumber(leaveNumber);//请假 leave
        toDayAttendanceVo.setCompleteNumber(completeList.size());
        if (todayPlanList.size() > 0) {
            toDayAttendanceVo.setUnCompleteNumber(todayPlanList.size() - workIngList.size() - completeList.size());
        }
        toDayAttendanceVo.setWorkIngNumber(workIngList.size());
        return toDayAttendanceVo;
    }

    @Override
    public WorkResorceVo workResource() throws HssException {
        WorkResorceVo workResorceVo = new WorkResorceVo();

        Set<String> carSet = new HashSet<>();
        Set<String> empSet = new HashSet<>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        QueryWrapper<RptCarWork> rptCarWorkQueryWrapper = new QueryWrapper<>();
        rptCarWorkQueryWrapper.lambda().eq(RptCarWork::getWorkDate, dateFormat.format(new Date()));
        List<RptCarWork> rptCarWorkList = rptCarWorkMapper.selectList(rptCarWorkQueryWrapper);
        Map<String, List<RptCarWork>> rptCarWorkCollect = rptCarWorkList.stream().filter(rptCarWork -> null != rptCarWork.getGridId()).collect(Collectors.groupingBy(RptCarWork::getGridId));

        QueryWrapper<RptEmployeeWork> rptEmployeeWorkQueryWrapper = new QueryWrapper<>();
        rptEmployeeWorkQueryWrapper.lambda().eq(RptEmployeeWork::getWorkDate, dateFormat.format(new Date()));
        List<RptEmployeeWork> rptEmployeeWorkList = rptEmployeeWorkMapper.selectList(rptEmployeeWorkQueryWrapper);
        Map<String, List<RptEmployeeWork>> rptEmployeeWorkCollect = rptEmployeeWorkList.stream().collect(Collectors.groupingBy(RptEmployeeWork::getGridId));

        List<Grid> gridList = iGridService.list();
        gridList.forEach(grid -> {
            List<RptCarWork> rptCarWorkGridList = rptCarWorkCollect.get(grid.getGridId());
            if (null != rptCarWorkGridList) {
                rptCarWorkGridList.forEach(rptCarWork -> {
                    carSet.add(rptCarWork.getGridId());
                });
            }
            List<RptEmployeeWork> rptEmployeeWorkGridList = rptEmployeeWorkCollect.get(grid.getGridId());
            if (null != rptEmployeeWorkGridList) {
                rptEmployeeWorkGridList.forEach(rptEmployeeWork -> {
                    empSet.add(rptEmployeeWork.getEmployeeId());
                });
            }
        });
        workResorceVo.setCarNumber(new BigDecimal(carSet.size()));
        workResorceVo.setEmpNumber(new BigDecimal(empSet.size()));
        Integer mainRoadNumber = (int) gridList.stream().filter(grid -> (null != grid.getLevelName() && grid.getLevelName().contains("主干道")) && (null != grid.getIsGuideboard() && grid.getIsGuideboard() == 1)).count();
        Integer secondaryMainRoadNumber = (int) gridList.stream().filter(grid -> (null != grid.getLevelName() && grid.getLevelName().contains("次干道")) && (null != grid.getIsGuideboard() && grid.getIsGuideboard() == 1)).count();
        Integer guideBoardNumber = (int) gridList.stream().filter(grid -> null != grid.getIsGuideboard() && grid.getIsGuideboard() == 1).count();
        workResorceVo.setGuideBoardNumber(guideBoardNumber);
        workResorceVo.setMainRoadNumber(mainRoadNumber);
        workResorceVo.setSecondaryMainRoadNumber(secondaryMainRoadNumber);
        return workResorceVo;
    }


    public AllWorkByAppVo allWorkByApp() {
        AllWorkByAppVo allWorkByAppVo = new AllWorkByAppVo();
        Date date = new Date();
        String now = DateUtil.formatDate(date);
        Map<Object, Object> jxqsMap = new HashMap<>();
        jxqsMap.put("workType", 2);
        jxqsMap.put("workDate", now);
        List<RptCarWork> jxqsResultList = rptCarWorkMapper.listByPlan(jxqsMap);

        Integer totalCount = jxqsResultList.size();
        Integer waitingCount = (int) jxqsResultList.stream().filter(t -> t.getAllStatus() == 0).count();
        Integer workingCount = (int) jxqsResultList.stream().filter(t -> t.getAllStatus() == 1).count();
        Integer finishCount = (int) jxqsResultList.stream().filter(t -> t.getAllStatus() == 3).count();
        System.out.println("=====================");
        // 清掃
        int totalCountQs = (int) jxqsResultList.stream().filter(t -> "清扫作业".equals(t.getWorkTypeName())).count();
        int finishCountQs = (int) jxqsResultList.stream().filter(t -> "清扫作业".equals(t.getWorkTypeName())).filter(t1 -> t1.getAllStatus() == 3).count();
        BigDecimal finishRateQs = (finishCountQs == 0) ? BigDecimal.ZERO : (new BigDecimal(finishCountQs).divide(new BigDecimal(totalCountQs), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP));
        // 灑水
        int totalCountSs = (int) jxqsResultList.stream().filter(t -> "洒水作业".equals(t.getWorkTypeName())).count();
        int finishCountSs = (int) jxqsResultList.stream().filter(t -> "洒水作业".equals(t.getWorkTypeName())).filter(t1 -> t1.getAllStatus() == 3).count();
        BigDecimal finishRateSs = (finishCountSs == 0) ? BigDecimal.ZERO : (new BigDecimal(finishCountSs).divide(new BigDecimal(totalCountSs), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP));

        // 汇总
        BigDecimal finishRateTotal = (finishCountQs + finishCountSs == 0) ? BigDecimal.ZERO : (new BigDecimal(finishCountQs + finishCountSs).divide(new BigDecimal(totalCountQs + totalCountSs), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP));

        JxqsWorkByAppVo jxqsWorkByAppVo = new JxqsWorkByAppVo();
        jxqsWorkByAppVo.setTotalCount(totalCount);
        jxqsWorkByAppVo.setFinishCount(finishCount);
        jxqsWorkByAppVo.setWorkingCount(workingCount);
        jxqsWorkByAppVo.setWaitingCount(waitingCount);
        jxqsWorkByAppVo.setTotalCountQs(totalCountQs);
        jxqsWorkByAppVo.setTotalCountSs(totalCountSs);
        jxqsWorkByAppVo.setFinishCountSs(finishCountSs);
        jxqsWorkByAppVo.setFinishCountQs(finishCountQs);
        jxqsWorkByAppVo.setFinishRateQs(finishRateQs);
        jxqsWorkByAppVo.setFinishRateSs(finishRateSs);
        jxqsWorkByAppVo.setFinishRateTotal(finishRateTotal);


        // 作业类型：2机械清扫；3垃圾清运；4垃圾转运
        // 状态：0未开始；1进行中；2已结束
        QueryWrapper<RptCarWork> carWorkQueryWrapper = new QueryWrapper<>();
        carWorkQueryWrapper.lambda().eq(RptCarWork::getWorkDate, now);
        carWorkQueryWrapper.lambda().eq(RptCarWork::getWorkType, 3);
        List<RptCarWork> rptCarWorkList = rptCarWorkMapper.selectList(carWorkQueryWrapper);
        //未开始数
        Integer ljqyResultOther = 0;
        //进行数
        Integer ljqyResultWorking = 0;
        //未完成数
        Integer ljqyResultUnfinished = 0;
        //完成数
        Integer ljqyResultFinish = 0;
        List<String> carIds = new ArrayList<>();

        for (RptCarWork rptCarWork : rptCarWorkList) {
            if (0 == rptCarWork.getStatus()) {
                ljqyResultOther++;
            } else if (1 == rptCarWork.getStatus()) {
                ljqyResultWorking++;
            } else if (2 == rptCarWork.getStatus()) {
                ljqyResultUnfinished++;
            } else if (3 == rptCarWork.getStatus()) {
                ljqyResultFinish++;
            }
            carIds.add(rptCarWork.getCarId());
        }
        //清运计划比
        BigDecimal finishRate = BigDecimal.ZERO;
        BigDecimal mileageSum = BigDecimal.ZERO;
        if (!carIds.isEmpty()) {
            //查询清运人员轨迹
            QueryWrapper<CarTrack> carTrackQueryWrapper = new QueryWrapper<>();
            carTrackQueryWrapper.lambda().orderByAsc(CarTrack::getTimestamp);
            carTrackQueryWrapper.lambda().eq(CarTrack::getWorkDay, LocalDate.now());
            carTrackQueryWrapper.lambda().in(CarTrack::getCarId, carIds);
            List<CarTrack> carTrackList = carTrackMapper.selectList(carTrackQueryWrapper);
            Map<String, List<CarTrack>> map = carTrackList.stream().collect(Collectors.groupingBy(CarTrack::getCarId));
            for (String carId : map.keySet()) {
                for (int i = 0; i < map.get(carId).size(); i++) {
                    if (i > 0) {
                        mileageSum = MathUtils.getBigDecimal(locationUtil.getDistance(map.get(carId).get(i - 1).getLat(), map.get(carId).get(i - 1).getLng(), map.get(carId).get(i).getLat(), map.get(carId).get(i).getLng())).add(mileageSum);
                    }
                }
            }
            Integer totalNumber = ljqyResultWorking + ljqyResultOther + ljqyResultFinish + ljqyResultUnfinished;
            if (0 != totalNumber) {
                finishRate = (new BigDecimal(ljqyResultFinish).divide(new BigDecimal(totalNumber), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100))).setScale(0, BigDecimal.ROUND_UP);
            }
        }

        LjqyWorkByAppVo ljqyWorkByAppVo = new LjqyWorkByAppVo();
        ljqyWorkByAppVo.setLjqyTotalCount(rptCarWorkList.size());
        ljqyWorkByAppVo.setLjqyResultUnfinished(ljqyResultUnfinished);
        ljqyWorkByAppVo.setLjqyResultFinish(ljqyResultFinish);
        ljqyWorkByAppVo.setLjqyResultWorking(ljqyResultWorking);
        ljqyWorkByAppVo.setLjqyResultOther(ljqyResultOther);
        ljqyWorkByAppVo.setFinishRate(finishRate);

        ljqyWorkByAppVo.setMileageSum(mileageSum.divide(new BigDecimal(1000), 0, BigDecimal.ROUND_HALF_UP));

        //垃圾转运
        QueryWrapper<RptCarWork> rptCarWorkQueryWrapper = new QueryWrapper<>();
        rptCarWorkQueryWrapper.lambda().eq(RptCarWork::getWorkDate, now);
        rptCarWorkQueryWrapper.lambda().eq(RptCarWork::getWorkType, 4);
        List<RptCarWork> rptCarWorkList1 = rptCarWorkMapper.selectList(rptCarWorkQueryWrapper);
        List<RptCarWork> rptCarWorkFilterList = rptCarWorkList1.stream().filter(rptCarWork -> null != rptCarWork.getStatus() && rptCarWork.getStatus() == 2).collect(Collectors.toList());

        LjzyWorkByAppVo ljzyWorkByAppVo = new LjzyWorkByAppVo();
        ljzyWorkByAppVo.setLjzyResultTotal(rptCarWorkList1.size());
        ljzyWorkByAppVo.setLjzyResultFinish(rptCarWorkFilterList.size());
        if (rptCarWorkFilterList.size() > 0) {
            ljzyWorkByAppVo.setLjzyFinishRate(new BigDecimal(rptCarWorkList1.size()).divide(new BigDecimal(rptCarWorkFilterList.size()), 0, BigDecimal.ROUND_HALF_UP));
        } else {
            ljzyWorkByAppVo.setLjzyFinishRate(BigDecimal.ZERO);
        }

        allWorkByAppVo.setJxqsWorkByAppVo(jxqsWorkByAppVo);
        allWorkByAppVo.setLjqyWorkByAppVo(ljqyWorkByAppVo);
        allWorkByAppVo.setLjzyWorkByAppVo(ljzyWorkByAppVo);
        return allWorkByAppVo;
    }

    public EmergencyByAppVo emergencyByApp() {

        EmergencyByAppVo emergencyByAppVo = new EmergencyByAppVo();
        emergencyByAppVo.setPlanCount(0);
        emergencyByAppVo.setResPlanCount(0);
        // 计划的
        QueryWrapper<TlEmergentPlan> tlEmergentPlanWrapper = new QueryWrapper<>();
        List<TlEmergentPlan> tlEmergentPlanList = tlEmergentPlanMapper.selectList(tlEmergentPlanWrapper);
        if (Objects.nonNull(tlEmergentPlanList) && tlEmergentPlanList.size() > 0) {
            emergencyByAppVo.setPlanCount(tlEmergentPlanList.size());
        }
        List<TlEmergentPlan> tlEmergentPlanFilterList = tlEmergentPlanList.stream().filter(tlEmergentPlan -> null != tlEmergentPlan.getStatus() && Integer.parseInt(tlEmergentPlan.getStatus()) == 0).collect(Collectors.toList());
        emergencyByAppVo.setPlanWorkIng(tlEmergentPlanFilterList.size());
        //预案
        QueryWrapper<TlEmergentResplan> tlEmergentResplanWrapper = new QueryWrapper<>();
        List<TlEmergentResplan> tlEmergentResplanList = tlEmergentResplanMapper.selectList(tlEmergentResplanWrapper);
        if (Objects.nonNull(tlEmergentResplanList) && tlEmergentResplanList.size() > 0) {
            emergencyByAppVo.setResPlanCount(tlEmergentResplanList.size());
        }

        return emergencyByAppVo;
    }


    public RptWorkVo getPlanList(WorkPlanTo workPlanTo) {
        List<Grid> gridList = gridMapper.selectList(new QueryWrapper<>());
        Map<String, Grid> gridMap = gridList.stream().collect(Collectors.groupingBy(Grid::getGridId, Collectors.collectingAndThen(toList(), grids -> grids.get(0))));


        QueryWrapper<RptCarWork> rptCarWorkQueryWrapper = new QueryWrapper<>();
        rptCarWorkQueryWrapper.lambda().orderByAsc(RptCarWork::getStatus);
        rptCarWorkQueryWrapper.lambda().eq(RptCarWork::getGridId, workPlanTo.getGridId());
        rptCarWorkQueryWrapper.lambda().eq(RptCarWork::getWorkDate, StringUtils.dateToStr(new Date(), "yyyy-MM-dd"));
        List<RptCarWork> rptCarWorkList = rptCarWorkMapper.selectList(rptCarWorkQueryWrapper);
        Map<String, List<RptCarWork>> rptCarWorkMap = rptCarWorkList.stream().collect(Collectors.groupingBy(RptCarWork::getPlanId));


        Set<RptCarWorkVo> rptCarWorkVoList = new HashSet<>();
        for (String planId : rptCarWorkMap.keySet()) {
            List<RptCarWork> rptCarWorkList1 = rptCarWorkMap.get(planId);
            if (null != rptCarWorkList1) {
                RptCarWorkVo rptCarWorkVo = new RptCarWorkVo();
                rptCarWorkList1.forEach(rptCarWork -> {
                    Grid grid = gridMap.get(rptCarWork.getGridId());
                    if (null != grid) {
                        rptCarWorkVo.setLevelName(grid.getLevelName());
                        rptCarWorkVo.setLngLat(grid.getLnglat());
                    }
                    rptCarWorkVo.setGridId(rptCarWork.getGridId());
                    rptCarWorkVo.setGridName(rptCarWork.getGridName());
                    rptCarWorkVo.setPlanId(rptCarWork.getPlanId());
                    rptCarWorkVo.setPlanName(rptCarWork.getPlanName());
                    rptCarWorkVo.setWorkType(rptCarWork.getWorkType());
                    rptCarWorkVo.setStatus(rptCarWork.getStatus());
                    rptCarWorkVo.setShiftId(rptCarWork.getShiftId());
                    rptCarWorkVo.setShiftName(rptCarWork.getShiftName());
                });
                rptCarWorkVoList.add(rptCarWorkVo);
            }
        }


        Set<RptEmployeeWorkVo> rptEmployeeWorkVoList = new HashSet<>();
        QueryWrapper<RptEmployeeWork> rptEmployeeWorkQueryWrapper = new QueryWrapper<>();
        rptEmployeeWorkQueryWrapper.lambda().orderByAsc(RptEmployeeWork::getStatus);
        rptEmployeeWorkQueryWrapper.lambda().eq(RptEmployeeWork::getGridId, workPlanTo.getGridId());
        rptEmployeeWorkQueryWrapper.lambda().eq(RptEmployeeWork::getWorkDate, StringUtils.dateToStr(new Date(), "yyyy-MM-dd"));
        List<RptEmployeeWork> rptEmployeeWorkList = rptEmployeeWorkMapper.selectList(rptEmployeeWorkQueryWrapper);
        rptEmployeeWorkList.forEach(rptEmployeeWork -> {
            RptEmployeeWorkVo rptEmployeeWorkVo = new RptEmployeeWorkVo();
            Grid grid = gridMap.get(rptEmployeeWork.getGridId());
            if (null != grid) {
                rptEmployeeWorkVo.setLevelName(grid.getLevelName());
                rptEmployeeWorkVo.setLngLat(grid.getLnglat());
            }
            rptEmployeeWorkVo.setGridId(rptEmployeeWork.getGridId());
            rptEmployeeWorkVo.setGridName(rptEmployeeWork.getGridName());
            rptEmployeeWorkVo.setPlanId(rptEmployeeWork.getPlanId());
            rptEmployeeWorkVo.setPlanName(rptEmployeeWork.getPlanName());
            rptEmployeeWorkVo.setStatus(rptEmployeeWork.getStatus());
            rptEmployeeWorkVo.setShiftId(rptEmployeeWork.getShiftId());
            rptEmployeeWorkVo.setShiftName(rptEmployeeWork.getShiftName());
            rptEmployeeWorkVoList.add(rptEmployeeWorkVo);
        });
        RptWorkVo rptWorkVo = new RptWorkVo();
        rptWorkVo.setRptCarWorkVoList(rptCarWorkVoList);
        rptWorkVo.setRptEmployeeWorkVoList(rptEmployeeWorkVoList);

        return rptWorkVo;
    }


    @Override
    public OnGuardRateVo employeeOnGuard() {
        Set<String> employeeSet = new HashSet<>();

        QueryWrapper<RptEmployeeWork> rptEmployeeWorkQueryWrapper = new QueryWrapper<>();
        rptEmployeeWorkQueryWrapper.lambda().eq(RptEmployeeWork::getWorkDate, StringUtils.dateToStr(new Date(), "yyyy-MM-dd"));
        List<RptEmployeeWork> rptEmployeeWorkList = rptEmployeeWorkMapper.selectList(rptEmployeeWorkQueryWrapper);
        for (RptEmployeeWork rptEmployeeWork : rptEmployeeWorkList) {
            employeeSet.add(rptEmployeeWork.getEmployeeId());
        }

        List<TlEmployee> tlEmployeeList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(employeeSet)) {
            QueryWrapper<TlEmployee> tlEmployeeQueryWrapper = new QueryWrapper<>();
            tlEmployeeQueryWrapper.lambda().in(TlEmployee::getId, employeeSet);
            tlEmployeeQueryWrapper.lambda().eq(TlEmployee::getOnguardstatus, 0);
            tlEmployeeList = tlEmployeeMapper.selectList(tlEmployeeQueryWrapper);
        }
        OnGuardRateVo onGuardRateVo = new OnGuardRateVo();
        onGuardRateVo.setOnGuardNumber(new BigDecimal(tlEmployeeList.size()));
        onGuardRateVo.setShiftNumber(new BigDecimal(employeeSet.size()));
        BigDecimal rate = BigDecimal.ZERO;
        if (0 > tlEmployeeList.size()) {
            rate = (new BigDecimal(employeeSet.size()).divide(new BigDecimal(tlEmployeeList.size()), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100))).setScale(0, BigDecimal.ROUND_UP);
        }
        onGuardRateVo.setRate(rate);
        return onGuardRateVo;
    }

    @Override
    public OnGuardRateVo carOnGuard() {
        Set<String> carSet = new HashSet<>();

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        QueryWrapper<RptCarWork> rptCarWorkQueryWrapper = new QueryWrapper<>();
        rptCarWorkQueryWrapper.lambda().eq(RptCarWork::getWorkDate, dateFormat.format(new Date()));
        List<RptCarWork> rptCarWorkList = rptCarWorkMapper.selectList(rptCarWorkQueryWrapper);
        for (RptCarWork rptCarWork : rptCarWorkList) {
            carSet.add(rptCarWork.getCarId());
        }
        List<TlCar> tlCarList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(carSet)) {
            QueryWrapper<TlCar> tlCarQueryWrapper = new QueryWrapper<>();
            tlCarQueryWrapper.lambda().in(TlCar::getId, carSet);
            tlCarQueryWrapper.lambda().eq(TlCar::getOnguardstatus, 0);
            tlCarList = tlCarMapper.selectList(tlCarQueryWrapper);
        }

        OnGuardRateVo onGuardRateVo = new OnGuardRateVo();
        onGuardRateVo.setOnGuardNumber(new BigDecimal(tlCarList.size()));
        onGuardRateVo.setShiftNumber(new BigDecimal(carSet.size()));
        BigDecimal rate = BigDecimal.ZERO;
        if (carSet.size() > 0) {
            rate = (new BigDecimal(tlCarList.size()).divide(new BigDecimal(carSet.size()), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100))).setScale(0, BigDecimal.ROUND_UP);
        }
        onGuardRateVo.setRate(rate);
        return onGuardRateVo;
    }
}
